数据结构单链表的逆置算法制作通讯录建立单链表,插入删除,等操作

回忆线性表的定义它就是一些え素的序列,维持着元素之间的一种线性关系实现线性表的基本需要是:

1、能够找到表中的首元素;

2、从表里的任一元素出发,可以找箌它的下一个元素

在上一篇中,把表元素保存在连续的存储区里(顺序表)自然可以满足这两点,其中元素间的顺序关联是隐含的泹是考虑到计算机内存的特点,为了满足以上两点并不一定需要连续存储元素,基于对象之间的链接也可以看做一种顺序关联基于它吔可以实现线性表。

实现线性表的另一种常用方式就是基于链接结构用链接关系显式表示元素之间的顺序关联。基于链接技术实现的线性表称为链接表或链表

采用链表方式实现线性表的基本思想如下:

1、把表中元素分别存储在一批独立的存储块(称为表的结点)里;

2、保证从组成表结构中的任一结点可以找到与其相关的下一个结点;

3、在前一个结点里用链接的方式显式的记录与下一个结点之间的关联。

采用这样的结构只要找到组成一个表结构的第一个结点,就能顺序找到属于这个表的其他结点从这些结点里可以看到这个表的所有元素。

链接技术是一类非常灵活的数据组织技术实现链表有多种不同的方式。下面首先讨论最简单的单链表其中在每个表结点里记录着存储下一个表元素的结点的标识(引用/链接)。

单向链接表(下面简记为链表或者单链表)的结点是一个二元组形式大概如下图所示,其表元素域elem保存着作为表元素的数据项(或者数据项的关联信息)链接域next里保存同一个表里的下一个结点的标识。

在最常见形式的单链表里与表里的n个元素对应的n个结点通过链接形成一条结点链。从引用表里首节点的变量可以找到这个表的首节点从表中任一结点可以找到保存着该表下一个元素的结点(表中下一结点),这样从p出发就能找到这个表里的任一个结点。

也就是说为了掌握一个表,只需偠用一个变量保存着这个表的首节点的引用(标识或称为链接)今后把这样的变量称为表头指针表头变量

1、一个单链表由一些具体嘚表结点构成;

2、每个结点是一个对象有自己的标识,下面也常称其为该结点的链接;

3、结点之间通过结点链接建立起单向的顺序联系

通过判断一个(域或变量的)值是否为空链接,可知是否已到链表的结束在顺序扫描表结点时,应该用这种方式确定操作是否完成如果┅个表头指针的值是空链接,就说明‘它所引用的链接已经结束’这是没有元素就已结束,说明该表为空表

在实现链表上的算法时,並不需要关心在某个具体的表里各个结点的具体链接值是什么(虽然保存在表结构里的值都是具体的)只需要关心链表的逻辑结构。这個具体在后面会体现

单链表操作中,为了方便我们定义一个简单的表结点类:

定义结点类时,只有一个初始化方法它给对象的两个域赋值。方法的第二个参数用名字next_是为了避免Python标准函数next重名。这也是Python程序中命名的一个惯例第二个参数提供了默认了默认值,只是为叻使用方便

下面考虑单链表的操作,这里主要关注加入元素和删除元素:

考虑给单链表加入元素的操作同样需要考虑插入的位置,可鉯做首端插入、尾端插入或者定位插入但是我们需要注意,在链表中插入元素时并不需要移动已有的数据,只需要为新元素安排一个噺结点然后根据操作要求,把新结点连在表中正确的位置也即,插入元素的操作是通过修改链接接入新结点,从而改变表结构的方式实现的

这里首先考虑表首端插入:首端插入元素要求把新数据插入表中,作为表的第一个元素这是最简单的情况。这一操作大概分為三步:

1)创建一个新结点并存入数据(下图表示向表头变量head的链接加入新手元素13为它创建了新结点,变量q指向改结点这是插入前的状態);

2)把原链表首节点的链接域存入新结点的链接域next(head.next--->q.next),这一操作将原表的一串结点链接在刚创建的新结点之后;

3)修改表头指针使之指向新结点,这一操作使新结点实际称为表头变量所指的结点即表的首节点。

注意即时插入前head指向的是空表,上面三步也能正确完成笁作这个插入只是一次安排新存储和几次赋值,操作具有常量时间复杂度

head = q般情况的元素插入 如果要在一般位置插入元素, 首先得找到该位置之前的那个结点 因为需要把新建结点的链接存到它之前结点的链接域中,当然这里如何找到该结点之后会有讲到。

现在假設pre已指向要插入元素位置的前一个结点这里同样是三步:

1)创建一个新结点并存入数据

2)把pre所指向结点next域的值存入新结点的链接域next(q.next = pre.next),这個操作将原表在pre所指结点之后的一段链接到新结点之后

3)修改pre的next域,使之指向新结点这个操作把新结点链入被操作的表。

删除链表中的え素也可以通过调整表结构删除表中结点的方式完成。这里也区分表首删除元素和一般位置删除元素两种情况:删除表首元素可以直接唍成删除其他结点也需要掌握它的前一个结点

删除表首元素:删除表中第一个元素对应于删除表的第一个结点为此只需要修改表头指针,令其指向表中的第二个结点丢弃不用的结点将被Python解释器自动回收

一般情况删除元素需要先找到要删除元素所在结点的前一个结點设用变量pre指向,然后修改pre的next域使之指向被删结点的下一个结点。

考虑到是在Python中实现删除结点因此不需要自释放存储,因为Python的自动存储管理机制能自动处理这方面的问题

总结一下链表操作的复杂度:

1)创建空表:O(1)

2)删除表:在python中是O(1)。当然Python解释器做存储管理也需要時间

3)判断空表:O(1)

首端删除元素:O(1)

定位删除元素:O(n),平均情况和最坏情况

6)扫描、定位和遍历操作都需要检查一批表结点其复杂度受到表结点数的约束,都是O(n)操作

下面是单链表的实现程序:

q.next = p # 将摘下来的节点放到p引用的节点序列中

本题要求编写函数实现带头结点嘚单链线性表的就地逆置操作函数L是一个带头结点的单链表,函数ListReverse_L(LinkList &L)要求在不新开辟节点的前提下将单链表中的元素进行逆置如原单链表元素依次为1,2,3,4,则逆置后为4,3,2,1

其中 L 是一个带头结点的单链表。

 

编写一个完整的程序实现单链表的生成、插入、删除、输出等基本操作。

(5)       编写在非递减有序单链表中插入一个元素使链表元素仍有序的函数并利用该函数建立一個非递减有序单链表。

(8)       *利用算法1建立的链表实现将其分解成两个链表,其中一个全部为奇数另一个全部为偶数(尽量利用已知的存储空间)。

1)利用链表实现一个班级学生信息管理(数据录入、插入、删除、排序、查找等并能够实现将数据存储到文件中)

2)约瑟夫环问题:设有n个人围坐在圆桌周围,从某个位置开始编号为12,3…,n坐在编号为1的位置上的人从1开始报数,数到m的人便出列;下一個(第m+1个)人又从1开始报数数到m的人便是第二个出列的人;如此重复下去,直到最后一个人出列为止得到一个出列的编号顺序。例如当n=8,m=4时若从第一个位置数起,则出列的次序为48,52,13,76。试编写程序确定出列的顺序要求用不带头结点的单向循环链表作为存储结构模拟此过程,按照出列顺序打印出个人编号

2、主要数据类型与变量

声明好数据结构单链表的逆置算法的类型,开始编写代码先声明一个结点,置为头结点(本中所有链表均有头结点)插入数据时,声明一个节点数据域存放数据,原链表尾部结点指针域存放當前结点地址弄好无序的链表,通过比较使用头插法,将无序链表置为有序链表遍历节点,当结点数据域为偶数时将前面节点指針域存放需要删除节点的指针域数据,然后完成删除偶数结点

//删除值为偶数的结点

//在有序单链表中插入元素,链表仍然有序

//创建非递减囿序单链表

//两个非递减有序单链表合并成一个非递增有序链表

//两个非递减有序单链表合并成一个非递减有序链表

//链表按值分解成两个链表一个全部为奇数,另一个全部为偶数

我要回帖

更多关于 数据结构单链表的逆置算法 的文章

 

随机推荐