数据结构-01-链表数据结构之单链表
来源:互联网 发布:java编译手机模拟器 编辑:程序博客网 时间:2024/05/21 10:38
本文中的所有代码均在github上的项目中:List_DataStructure
一.链表:
1.1 链表的概念:
链表是一种物理存储单元上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的。链表由一系列结点(链表中每一个元素称为结点)组成,结点可以在运行时动态生成。
每个结点包括两个部分内容:一是存储数据元素的数据域,另一个是存储其他结点地址的指针域(不同种类的链表存储的结点地址不同)。
1.2 链表的种类:
链表根据每个结点存储的指向下一结点的链接不同而分为几类
单链表:结构最简单的链表,每个结点中都有指向下一结点的地址
双链表:对单链表做了部分加强,每个结点中都有两个地址,分别指向上一结点和下一结点
环形链表:尾结点中存储有头结点的地址,整个链表形成了一个封闭的环
二.单链表:
单链表又名单向链表,其特点是链表的链接方向是单向的,对链表的访问要通过顺序读取的方式,从头部开始遍历链表
2.1 单链表的基本结构:
单链表的开始是一个头指针,每个结点中都有指向下一结点的地址,尾结点中的地址为nullptr
单链表的C++实现:
1.首先创建单链表的结点类
template<typename Type> class SingleLinkedList;template<typename Type>class SingleLinkedListNode{private: //将链表类声明为友元 friend typename SingleLinkedList<Type>; //构造函数和析构函数 SingleLinkedListNode() :pnext(nullptr){} SingleLinkedListNode(const Type item, SingleLinkedListNode<Type> * next = nullptr) :data(item),pnext(next){} ~SingleLinkedListNode() { pnext = nullptr; }public: //创建公共方法,用于获取结点中的数据 Type GetData();SingleLinkedListNode<Type>&);private: //结点类的私有属性,结点数据和下一结点的地址 Type data; SingleLinkedListNode * pnext;};
2.创建单链表类
#include"SingleLinkedListNode.h"template <typename Type>class SingleLinkedList{public: //构造函数和析构函数 SingleLinkedList() :head(new SingleLinkedListNode<Type>()){} ~SingleLinkedList() { MakeEmpty(); delete head; } //对单链表的基本操作 void MakeEmpty(); void Insert(Type item, int i = 0); void Remove(int i = 0); void RemoveAll(Type item); //返回单聊表的基本信息 int length(); Type Get(int i); //查找和排序 SingleLinkedList<Type> * SequentialSearch(Type item); //基础功能 void Print();private: //链表的头节点是私有的 SingleLinkedListNode<Type> *head;};
3.创建一个单链表对象:
SingleLinkedList<int> list;
根据空参构造方法,创建单链表对象时初始化了一个私有的,没有数据的头结点*head
2.2 向单链表中插入数据:
单链表的一个可用的Insert( )方法版本:
该版本不用按照插入位置的不同(头尾体)而分情况实现,比较简洁
//向单链表中插入元素template <typename Type>void SingleLinkedList<Type>::Insert(Type item, int i = 0) { if (i < 0){ cout << "请输入一个大于0的数" << endl; } SingleLinkedListNode<Type> *pmove = head; SingleLinkedListNode<Type> *pnode = new SingleLinkedListNode<Type>(item); //循环条件是j<i,且pmove的地址不能为空 for (int j = 0; j < i&&pmove; j++){ pmove = pmove->pnext; } //插入点越界 if (pmove == nullptr){ cout << "数据插入位置错误,单链表没那么长!" << endl; } pnode->pnext = pmove->pnext; pmove->pnext = pnode;}
在中间部分插入数据
以中间部分插入为主讨论:
1,首先创建两个结点类型指针pmove 和pnode
2,将pmove指针移动到插入点,如上图,插入位置为a2,a3之间,pmove指向a2
3,变更结点中存储的地址以实现结点插入
pnode->pnext = pmove->pnext; //第一步pmove->pnext = pnode; //第二步
第一步:待插入节点pnode的下一结点地址pnext指向a3,a3的地址为a2结点的下一结点地址pnext,也是pmove的pnext,即pmove->pnext
第二步:更改a2结点的下一结点地址pnext,使其指向待插入节点pnode
如上图所示,s为待插入节点pnode,p为插入点位置pmove
在头部插入数据
在尾部插入数据
测试单链表的插入方法:
int main() { SingleLinkedList<int> list; //向链表中插入20个数据 for (int i = 0; i < 20; i++) { list.Insert(i*4,i); } //在链表头部插入数据 list.Insert(10,0); //在链表尾部插入数据 list.Insert(100,21); list.Print(); cin.get(); return 0;}
执行结果:
2.3 删除单链表中的数据:
执行原理与添加数据相似,创建两个结点类型指针pdel和pmove
pdel指向待删除元素,pmove指向待删除结点的前一个结点
//删除单链表中的元素template <typename Type>void SingleLinkedList<Type>::Remove(int i = 0) { if (i < 0){ cout << "请输入一个大于0的数" << endl; } SingleLinkedListNode<Type> *pmove = head, *pdel; for (int j = 0; j < i&&pmove->pnext; j++){ pmove = pmove->pnext; } if (pmove->pnext == nullptr){ cout << "删除出错,链表没有那么长!" << endl; } pdel = pmove->pnext; pmove->pnext = pdel->pnext; delete pdel;}
2.3 单链表的其他方法:
2.3.1 销毁单链表
析构函数调用了此方法
//删除单链表template <typename Type>void SingleLinkedList<Type>::MakeEmpty() { SingleLinkedListNode<Type> *pdel; while (head->pnext != nullptr) { pdel = head->pnext; head->pnext = pdel->pnext; delete pdel; }}
2.3.2 返回单链表长度
//返回单链表长度template<typename Type>int SingleLinkedList<Type>::length() { SingleLinkedListNode<Type> *pmove = head->pnext; int count = 0; while (pmove != nullptr) { pmove = pmove->pnext; count++; } return count;}
2.3.3 打印单链表中的所有数据
//打印单链表中的所有数据template<typename Type>void SingleLinkedList<Type>::Print() { SingleLinkedListNode<Type> *pmove = head->pnext; cout << endl << "head"; while (pmove != nullptr) { cout << "->" << pmove->data; pmove = pmove->pnext; } cout << "-over" << endl;}
- 数据结构-01-链表数据结构之单链表
- 数据结构之链表
- 数据结构之链表
- 数据结构之链表
- 数据结构之链表
- 数据结构之链表
- 数据结构之链表
- 数据结构之链表
- 数据结构之链表
- 数据结构之链表
- 数据结构之链表
- 数据结构之链表
- 数据结构之链表
- 数据结构之链表
- 数据结构之链表
- 数据结构之链表
- 数据结构之链表
- 数据结构之链表
- ajax 验证用户名是否已存在
- r语言常用函数(二)
- ArcGIS二次开发及应用学习的最佳网站
- Java基础--1数据类型
- 2017 ACM-ICPC 青岛站
- 数据结构-01-链表数据结构之单链表
- 大端,小端
- 美团和滴滴,跨领域的竞争
- scala methods review
- 编写词法分析器有感~~~
- Linux中基础笔记(必备知识)包含常用指令以及tomcat搭建 系列3
- HashMap 的源码分析
- 在安防领域如此“受宠”的POE交换机到底该怎么选?
- LineNumberReader读取文件的行数