实验一 线性表的顺序存储与实现_C++线性表的链式存储结构

为了解决顺序存储不足:用线性表另外一种结构-链式存储。在顺序存储结构(数组描述)中,元素的地址是由数学公式决定的,而在链式储存结构中,元素的地址是随机分布的,每个元素都有一个明确的指针指向线性表的下一个元素的位置(即地址)。

线性表的链式存储结构的特点是用一组任意的存储单元存储线性表的数据元素,这组存储单元可以是连续的,也可以是不连续的。在顺序结构中,每个数据元素只需要存数据元素信息就行了,而在链式结构中,除了存储数据元素信息外,还要存储它的后继元素的存储地址。所以一般结点包括两个信息:数据和指针。链表就是n个节点组成的,如果每个结点只包含一个指针,那么就是单链表。

有头有尾:我们把链表中第一个结点的存储位置叫作头指针,那么整个链表的存取就必须是从头指针开始进行的。而线性链表的最后一个结点指针为空(NULL)。从下图中可以看到,结点都是由两部分组成,数据域和指针域。

实验一 线性表的顺序存储与实现_C++线性表的链式存储结构_第1张图片

有时,为了更方便对链表进行操作,会在单链表的第一个结点前加一个头结点。头结点的数据域可以不存储任何信息,也可以存储如线性表长度等附加信息,头结点的指针域存储指向第一个结点的指针。

实验一 线性表的顺序存储与实现_C++线性表的链式存储结构_第2张图片

头指针和头结点的异同 1. 指链表指向第一个结点的指针,若链表有头结点,则是指向头结点的指针。

  1. 头指针具有标识作用,所以常用头指针冠以链表的名字。
  2. 无论链表是否为空,头指针均不为空。头指针是链表的必要元素。

(这句话真的歧义,若没有头结点,头指针head指向第一个节点,当空表时,head=NULL。应该是必须要有头指针。) {% note info no-icon %}

头结点

(1)头结点是为了操作的统一和方便而设立的,放在第一个元素的结点之前,其数据域一般无意义(也可存放链表的长度)

(2)有了头结点,对在第一元素结点前插入结点和删除第一结点,其操作与其它结点的操作就统一了。

(3)头结点不一定是链表必须的要素。

链式存储结构的线性表进行的基本操作。主要包括:

  • 插入:操作方式为在指定元素前插入、在指定元素之后插入、在指定位置完成插入
  • 删除:操作方式可分为删除指定元素、删除指定位置的元素,删除第一个元素,删除最后一个元素
  • 显示数据
  • 查找:查询指定的元素(可根据某个数据成员完成查询操作)
  • 定位操作:定位指定元素的序号
  • 更新:修改指定元素的数据
  • 数据文件的读写操作
  • 计算链表的长度

实验一 线性表的顺序存储与实现_C++线性表的链式存储结构_第3张图片

定义一个结点类

/*Define a friend class to facilitate direct manipulation of data*/

链表的主要函数构成

template 

各个函数的实现

Print()函数

template

创建一个新的结点,并为其分配空间

template 

清除某一个节点,释放空间

template

获得链表的长度

template

前插法建立链表

从一个空表开始,重复读入数据,执行以下两步 (1)生成新的结点,将读入数据存放在新节点的的_data域中 (2)将该节点插入到链表的前端,直到读入到结束符为止。

template 

用后插法建立链表

需要设置一个尾部指针end,总是指向新链表的最后一个节点,新节点链接到它所指链尾节点的后面。end最初要置于附加头节点位置

template 

从尾部删除一个数据

考虑只有一个节点情况,多个结点的情况。 多个结点,首先找到尾部元素,然后调用clear()函数,清理掉尾部第一个元素

template 

从头部删除一个元素

实现方法和从尾部删除一个元素基本相似,不多加以解释

template 

查找某一个元素

遍历整个链表,并将其数据_data与x进行比对,如果是其他类型就需要重载运算符==

template 

在第pos个元素后插入一个新元素

创建一个新的结点,通过移动begin指针,pos控制指针最终位置,将新元素插入到之后

template 

在第pos个元素插入一个新元素

因为写了一个在后面插入的函数,为了偷懒,就直接调用了Insert_right()这个函数

template 

在第pos个元素前插入一个新元素

创建一个新的结点,通过移动begin指针,pos控制指针最终位置,将新元素插入到之前,与插入之后实现方法基本类似,只是需要注意pos的控制

template 

删除第pos个元素

依旧利用pos控制指针位置,然后删除就ok

template 

查找某一个元素位置并返回其位置

用一个temp进行计数,遍历整个链表,一一进行比对其——data数据(若是其它类型就需要重载运算符“=”,后面的函数提到比对的都需要实现,才能进行比对)比对成功就返回,其它类的实现依然需要重载

template 

删除指定的元素遍历链表

一一比对,找到就调用chear()函数删除并清理空间

template 

更新指定元素的值

遍历链表,一一比对(前面提到了重载的),找到要更新的元素后就将新的值赋值给它

template 

链表的数据写入文件

能实现所有数据的储存,但是如果是其他类,写入没有问题,如果想从同一个文件中读入之前写的数据,遇到一些困难没有实现,但是基本数据类型是ok的,测试函数就表现出来了的(其它类的读入需要重载输入流,输出流)

template 

从文件读入先前写入的数据,上面有提到只能满足基本数据类型

template 

为了更好的操作,测试相关函数的功能,写了这样一个函数来从文件得到链表长度的函数

template 

写到这基本上函数的功能都实现了,这个链表结构肯定有很多不完善的地方,第一次写博客,还望大家见谅。上面提到了其它类的重载问题,我就把写的一个point类分享给大家。

class 

一个输入之后的展示

实验一 线性表的顺序存储与实现_C++线性表的链式存储结构_第4张图片

实验一 线性表的顺序存储与实现_C++线性表的链式存储结构_第5张图片

继续加油!

以上是C++链式线性表使用过程中最常用的主要操作,相关完整代码已经push到GitHub,需要的小伙伴自行clone,如果觉得还不错的话,欢迎Star,这里是传送门C++顺序表,小编也是一名学生,如果有什么写的不对的地方,大家在下方给我留言,我们一起讨论!接下来我会更新其他相关算法,敬请期待!
北徯的博客​www.xiangjunhong.com

你可能感兴趣的:(实验一,线性表的顺序存储与实现)