动态单向链表的C++实现

2024-08-22 10:18
文章标签 动态 c++ 实现 链表 单向

本文主要是介绍动态单向链表的C++实现,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一.概念

链表是一种特殊的数组,它的每个元素称为节点,每个节点包括两个部分:

  • 数据域:存放数据,此部分与数组相同
  • 指针域:存放了下一个节点的地址(单向链表)、存放上一个和下一个节点的地址(双向链表)

其结构如下图所示


链表比数组多了指针域,因为链表结构是通过上一个节点的指针域去找下一个数据,比如有一个链表ABCD四个节点,其中A节点是链表的第一个节点,如果要访问D节点里边的数据。操作如下:

  1. 先通过A节点的指针域找到B节点
  2. 再通过B节点的指针域找到C节点
  3. 再通过C节点的指针域找到D节点
  4. 获取D节点数据域的数据

当遍历链表中的数据时,这种方法相比数组一般更加耗时,但是他的好处在于当插入和删除数据时非常方便,数组的插入和删除需要调整之后的每个数据,而链表则只需要调整结点的指针即可,如下图所示,删除同理


二.头指针和头结点

      头指针用来唯一确定单链表的身份,头指针指向链表的第一个结点,若第一个结点不存放数据,则为头结点。链表可以没有头结点,但必须有头指针,没有头指针的话链表也就不存在了。头结点的数据域可以不存放任何信息,也可以存放链表的长度等信息。

总结:

     头指针:

  • 在线性表的链式存储结构中,头指针是指链表指向第一个结点的指针,若链表有头结点,则头指针就是指向链表头结点的指针。
  • 头指针具有标识作用,常用头指针冠以链表的名字。
  • 无论链表是否为空,头指针均不为空。头指针是链表的必要元素。

头结点:

  • 头结点是为了操作的统一与方便而设立的,放在第一个元素结点之前,其数据域一般无意义(有些情况下也可存放链表的长度等等)。
  • 有了头结点后,对在第一个元素结点前插入结点和删除第一个结点,其操作与对其它结点的操作统一了。即操作任何位置时代码相同,更加方便。
  • 头结点不是链表所必需的。

三.实践

声明: LinkList.h

//
// Created by 开机烫手 on 2018/3/11.
//
#ifndef LINEARLIST_LINKLIST_H
#define LINEARLIST_LINKLIST_Hnamespace xq {typedef struct node {int data;struct node *next;} NODE;class LinkList {private:NODE* head;int len;LinkList(const LinkList&);public:LinkList();~LinkList();bool clearList();bool isEmpty();int length();void getElem(int, int *);int locateElem(int);bool insert(int, int);bool delete_(int,int*);void sort();void print();bool push_back(int);};}
#endif //LINEARLIST_LINKLIST_H

类实现:LinkList.cpp

//
// Created by 开机烫手 on 2018/3/11.
//
#include <iostream>
#include "LinkList.h"using namespace xq;
using namespace std;LinkList::LinkList() {head = new NODE;    // 创建头结点head->next = nullptr;len = 0;
}LinkList::~LinkList() {NODE *p = head->next;NODE *q;while (p) {q = p->next;delete p;p = q;}
}bool LinkList::clearList() {NODE *p = head->next;NODE *q;while (p) {q = p->next;delete p;p = q;}len = 0;head->next = nullptr;return true;
}bool LinkList::isEmpty() {return len == 0;
}int LinkList::length() {return len;
}void LinkList::getElem(int i, int *e) {if (i <= 0 || i > len || len == 0) {*e = -999;return;}int j = 1;NODE *p = head->next;while (j < i && p) {p = p->next;j++;}*e = p->data;
}int LinkList::locateElem(int e) {int i = 1;NODE *p = head->next;while (p) {if (p->data == e)return i;p = p->next;i++;}return -1;
}bool LinkList::insert(int i, int e) {if (i <= 0 || i-1 > len)return false;int j = 1;NODE *p = head;while (p && j < i) {p = p->next;j++;}NODE *s = new NODE;s->data = e;s->next = p->next;p->next = s;len++;return true;
}void LinkList::print() {if (len == 0) {cout << "list is empty!" << endl;return;}NODE *p = head->next;while (p) {cout << p->data << ' ';p = p->next;}cout << endl;
}bool LinkList::delete_(int i, int *e) {if (i <= 0 || i > len)return false;NODE *q = head;int j = 1;NODE *p = head->next;while (j < i) {q = p;p = p->next;j++;}*e = p->data;q->next = p->next;len--;delete p;return true;
}bool LinkList::push_back(int e) {NODE *p = head->next;while (p->next) {p = p->next;}NODE *s = new NODE;s->data = e;p->next = s;s->next = nullptr;len++;return true;
}void LinkList::sort() {if (len <= 1)return;int temp;NODE *p, *q;for (int i = 0; i < len - 1; i++) {p = head->next;q = head->next->next;for (int j = 0; j < len - 1 - i; j++) {if ((p->data) > (q->data)) {temp = p->data;p->data = q->data;q->data = temp;}p = p->next;q = q->next;}}
}

代码测试:main.cpp

#include <iostream>
#include "LinkList.h"using namespace std;
using namespace xq;int main() {cout << "----------List test programe!---------- " << endl;LinkList list1;cout << "is empty " << list1.isEmpty() << endl;list1.insert(1, 1);cout << "is empty " << list1.isEmpty() << endl;list1.clearList();cout << "is empty " << list1.isEmpty() << endl;list1.insert(1, 1);list1.insert(2, 2);list1.insert(3, 3);list1.insert(4, 5);list1.insert(5, 6);list1.print();list1.insert(4, 4);list1.print();int c;list1.delete_(5, &c);list1.print();int location = list1.locateElem(3);cout << "location is " << location << endl;int num2;list1.getElem(4, &num2);cout << "num2 = " << num2 << endl;list1.push_back(10);list1.push_back(5);list1.push_back(7);list1.push_back(2);list1.print();list1.sort();cout << "sort " ;list1.print();return 0;
}

程序输出为:

----------List test programe!----------
is empty 1
is empty 0
is empty 1
1 2 3 5 6
1 2 3 4 5 6
1 2 3 4 6
location is 3
num2 = 4
1 2 3 4 6 10 5 7 2
sort 1 2 2 3 4 5 6 7 10

这篇关于动态单向链表的C++实现的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1095990

相关文章

C#借助Spire.XLS for .NET实现在Excel中添加文档属性

《C#借助Spire.XLSfor.NET实现在Excel中添加文档属性》在日常的数据处理和项目管理中,Excel文档扮演着举足轻重的角色,本文将深入探讨如何在C#中借助强大的第三方库Spire.... 目录为什么需要程序化添加Excel文档属性使用Spire.XLS for .NET库实现文档属性管理Sp

C++ move 的作用详解及陷阱最佳实践

《C++move的作用详解及陷阱最佳实践》文章详细介绍了C++中的`std::move`函数的作用,包括为什么需要它、它的本质、典型使用场景、以及一些常见陷阱和最佳实践,感兴趣的朋友跟随小编一起看... 目录C++ move 的作用详解一、一句话总结二、为什么需要 move?C++98/03 的痛点⚡C++

Python+FFmpeg实现视频自动化处理的完整指南

《Python+FFmpeg实现视频自动化处理的完整指南》本文总结了一套在Python中使用subprocess.run调用FFmpeg进行视频自动化处理的解决方案,涵盖了跨平台硬件加速、中间素材处理... 目录一、 跨平台硬件加速:统一接口设计1. 核心映射逻辑2. python 实现代码二、 中间素材处

Java数组动态扩容的实现示例

《Java数组动态扩容的实现示例》本文主要介绍了Java数组动态扩容的实现示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧... 目录1 问题2 方法3 结语1 问题实现动态的给数组添加元素效果,实现对数组扩容,原始数组使用静态分配

Python实现快速扫描目标主机的开放端口和服务

《Python实现快速扫描目标主机的开放端口和服务》这篇文章主要为大家详细介绍了如何使用Python编写一个功能强大的端口扫描器脚本,实现快速扫描目标主机的开放端口和服务,感兴趣的小伙伴可以了解下... 目录功能介绍场景应用1. 网络安全审计2. 系统管理维护3. 网络故障排查4. 合规性检查报错处理1.

Python轻松实现Word到Markdown的转换

《Python轻松实现Word到Markdown的转换》在文档管理、内容发布等场景中,将Word转换为Markdown格式是常见需求,本文将介绍如何使用FreeSpire.DocforPython实现... 目录一、工具简介二、核心转换实现1. 基础单文件转换2. 批量转换Word文件三、工具特性分析优点局

Springboot3统一返回类设计全过程(从问题到实现)

《Springboot3统一返回类设计全过程(从问题到实现)》文章介绍了如何在SpringBoot3中设计一个统一返回类,以实现前后端接口返回格式的一致性,该类包含状态码、描述信息、业务数据和时间戳,... 目录Spring Boot 3 统一返回类设计:从问题到实现一、核心需求:统一返回类要解决什么问题?

详解C++ 存储二进制数据容器的几种方法

《详解C++存储二进制数据容器的几种方法》本文主要介绍了详解C++存储二进制数据容器,包括std::vector、std::array、std::string、std::bitset和std::ve... 目录1.std::vector<uint8_t>(最常用)特点:适用场景:示例:2.std::arra

C++构造函数中explicit详解

《C++构造函数中explicit详解》explicit关键字用于修饰单参数构造函数或可以看作单参数的构造函数,阻止编译器进行隐式类型转换或拷贝初始化,本文就来介绍explicit的使用,感兴趣的可以... 目录1. 什么是explicit2. 隐式转换的问题3.explicit的使用示例基本用法多参数构造

Java使用Spire.Doc for Java实现Word自动化插入图片

《Java使用Spire.DocforJava实现Word自动化插入图片》在日常工作中,Word文档是不可或缺的工具,而图片作为信息传达的重要载体,其在文档中的插入与布局显得尤为关键,下面我们就来... 目录1. Spire.Doc for Java库介绍与安装2. 使用特定的环绕方式插入图片3. 在指定位