线性表的链式表示

单链表是个啥?
想象一下,你有一串珠子,每个珠子里可以放点东西,比如小石子或者小糖果。在每个珠子上,除了放东西的地方,还有一个小钩子,可以挂到下一个珠子上。这串珠子就是单链表。
单链表长啥样?
珠子:就是链表里的结点,用来放东西。
小钩子:就是指针,指向下一个珠子。
带头的珠子:就是头结点,它可能啥也不放,或者放点重要信息,比如这串珠子有多长。
带头的钩子:就是头指针,它总是指向这串珠子的第一个珠子。
单链表有啥好处?
它不需要珠子(存储空间)排成一长排,可以随便放,节省空间。
往里面加珠子或者拿出珠子的时候,只需要动动钩子(修改指针),不用把其他珠子搬来搬去。
单链表有啥不好?
每个珠子上的小钩子占地方,可能会浪费点空间。
如果想找某个特定的珠子,你得从头开始,一个个看过去,效率有点低。
怎么玩单链表?
从头开始加珠子:每次加新珠子,都把它挂在带头的珠子后面,这样加的顺序和珠子的顺序是反的。
从后面加珠子:需要一个特殊的钩子(尾指针),它总是指向最后一个珠子,这样加的珠子顺序和输入的顺序是一样的。
找珠子:不管是按编号还是按里面的东西来找,都得从头开始一个个看。
加新珠子:找到要加的位置前的那个珠子,然后把新珠子挂上去。
操作的时候注意啥?
加珠子的时候,主要时间都花在找位置了,找到了位置,加珠子就快了。
因为珠子是一串一串的,所以找东西就得一个一个看。

单链表
想象一下,单链表就像一排排的座位,每个座位上都有一个人,而且每个人手里都拿着一张纸条,上面写着他后面那个人的名字。如果你想找到第10个人,你得从第一个人开始,一个一个地问,直到找到第10个。
删除操作:如果你想让第10个人离开队伍,你得先找到第9个人,然后告诉第11个人,以后第9个人就是你的前一个人了,然后把第10个人从队伍里踢出去。
数人数:如果你想要知道队伍里有多少人,你也得从第一个人开始数,一直数到最后一个人。


双链表
双链表就像是升级版的单链表,每个人不仅知道后面的人是谁,还知道前面的人是谁。这样,你就可以从两头往中间找人了。
插入操作:如果你想在第10个人后面加一个人,你就得让第10个人知道后面的人变了,新来的人要知道他前面是第10个,后面是第11个。
删除操作:如果你想让第10个人离开,你就得让第9个人和第11个人知道他们现在是邻居了,然后把第10个人赶走。


循环链表
循环链表就像是把单链表或者双链表的尾巴接在了一起,形成了一个圈。
循环单链表:最后一个知道的人,他的纸条上写的是第一个人的名字。如果你想判断这个圈里有没有其他人,就看第一个人手里的纸条是不是写的自己的名字。
循环双链表:这个圈更复杂,第一个人不仅要知道最后一个,最后一个也要反过来知道第一个。


静态链表
静态链表就像是一排固定的座位,每个人的位置是固定的,但是他们可以通过手里的纸条知道其他人的位置。
基本操作:插入和删除人的时候,你只需要改改纸条上的名字,不用真的移动座位。
优点:这样的好处是,你不用搬来搬去,节省力气。
缺点:但是,如果你想找到某个人,你得从第一个座位开始,一个一个地看纸条,直到找到。
适用场景:这种链表适合那些人不会随便换座位,或者你不在乎花时间去找人的场景。

顺序表和链表的区别:
存取方式:
顺序表就像书架上排好的书,你可以随手拿起任何一本,也可以从头一本本看过去。
链表就像一串珠子,要拿到中间的珠子,你得从第一个珠子开始,一个一个摸过去。
存储方式:
顺序表的元素在内存里是挨着的,就像邻居一样,你可以直接走到邻居家。
链表的元素在内存里可能散落各处,但它们通过一个叫指针的东西相互认识。
查找操作:
如果顺序表是有序的,找东西可以像查字典一样,从中间开始,然后往左或往右找。
如果顺序表没排序或者用链表,找东西就得像翻书一样,一页一页翻。
插入和删除:
在顺序表里插入或删除东西,可能要像搬砖一样,把其他东西挪开,腾出位置。
在链表里,插入或删除就简单多了,只要改改指针,告诉其他珠子,这个位置换人了。
空间分配:
顺序表的空间一开始就定好了,如果不够了,就得换大房子,搬家挺麻烦的。
链表的空间就像搭帐篷,需要多大就搭多大,灵活多了。
选择哪种:
如果你不确定将来要放多少东西,或者经常要按顺序拿东西,顺序表可能更适合。
如果你经常要加东西或减东西,或者环境里指针用得顺手,链表可能更合适。
 

知识点链接
单链表的定义
单链表是一种数据结构,它使用一组存储单元来存储线性表中的元素。每个存储单元称为一个结点,它包含两个部分:
数据域:存放数据元素。
指针域:存放指向其后继结点的指针。
结构
结点结构:包括数据域和指针域。
头指针:用来标识单链表,始终指向单链表的第一个节点。
头结点:单链表的第一个结点前附加的结点,其数据域可以为空或存放表长等信息。
优点
解决了顺序表需要大量连续存储单元的缺点。
插入和删除操作不需要移动元素,只需修改指针。
缺点
单链表需要额外的指针域,可能会浪费存储空间。
查找特定结点需要从表头开始遍历,效率较低。
基本操作的实现
头插法建立单链表:从空表开始,生成新结点,将数据存放到新结点的数据域中,然后将新结点插入到当前链表的表头。时间复杂度为O(1)每个结点,总时间复杂度为O(n)。
尾插法建立单链表:将新结点插入到当前链表的表尾,需要增加一个尾指针。时间复杂度与头插法相同。
按序号查找结点值:时间复杂度为O(n)。
按值查找表结点:时间复杂度为O(n)。
插入结点操作:首先查找插入位置的前驱节点,然后连接前驱节点和后继节点。主要时间开销在于查找第i-1个元素,时间复杂度为O(n)。

Tips
插入操作的时间复杂度主要取决于查找第i-1个元素的时间,如果直接在给定的节点下进行插入,则时间复杂度为O(1)。
由于链表本身的特点,查找操作需要依次遍历。

单链表
删除结点操作:删除第i个结点需要先检查位置的合法性,然后找到第i-1个结点(前驱结点),并将其链接到被删除结点的后继结点上。这个过程的时间复杂度是O(n),因为需要遍历链表直到找到第i-1个结点。
求表长操作:计算链表中数据结点的个数,从第一个结点开始,顺序访问每个结点。时间复杂度同样是O(n)。
双链表
概念:双链表的每个结点有两个指针, prior 指向前驱结点, next 指向后继结点,这使得双向遍历成为可能。
插入操作:在结点 p 后插入新结点 s ,需要更新 s 的 next 和 prior ,以及 p 的 next 和 prior 。
删除操作:删除 p 的后继结点 q ,需要更新 p 的 next 和 q 的 prior ,然后释放 q 的内存。
循环链表
循环单链表:最后一个结点的指针指向头结点,形成一个环。判空条件是头结点的指针是否等于头指针。循环单链表通常只设尾指针,提高头尾操作的效率。
循环双链表:与循环单链表类似,但头结点的 prior 指针也指向表尾结点。当循环双链表为空时,头结点的 prior 和 next 域都指向自己。
静态链表
基本结构:使用数组来描述链式存储结构,结点包含数据域 data 和指针域 next ,指针是结点的相对地址(数组下标)。
特点:静态链表以 next==-1 作为结束标志。插入和删除操作与动态链表相同,只需修改指针,不需要移动元素。需要预先分配一块连续的内存空间。
优点:增、删操作不需要大量移动元素。
缺点:不能随机存取,只能从头结点开始查找;容量固定不可变。
适用场景:不支持指针的低级语言;数据元素数量固定不变的场景,如操作系统的文件分配表FAT。

存取(读写)方式
顺序表:可以顺序存取,也可以随机存取。这意味着可以直接访问任何位置的元素,而不需要按顺序遍历。
链表:只能从表头顺序存取元素。访问链表中的元素需要从表头开始,逐个遍历到所需的位置。
逻辑结构与物理结构
顺序存储:逻辑上相邻的元素在物理存储位置上也相邻,通常使用数组实现。
链式存储:逻辑上相邻的元素在物理存储位置上不一定相邻,它们通过指针链接来表示逻辑关系,通常使用链表实现。
查找、插入和删除操作
按值查找:
顺序表(有序):可采用折半查找,时间复杂度为 O(\log_2 n)。
顺序表(无序)和链表:时间复杂度均为 O(n)。
按序号查找:
顺序表:支持随机访问,时间复杂度为 O(1)。
链表:平均时间复杂度为 O(n)。
插入、删除操作:
顺序表:平均需要移动半个表长的元素,这在元素数量较大时可能效率较低。
链表:只需修改相关结点的指针域,不需要移动其他元素,因此在插入和删除操作上更加高效。
空间分配
顺序存储:
静态分配:存储空间固定,一旦满则无法扩充,可能导致内存溢出。
动态分配:可以扩充空间,但需要移动数据,效率较低。
链式存储:空间分配非常灵活,可以根据需要动态增加或减少节点。
选取存储结构
基于存储的考虑:
如果难以估计线性表的长度或存储规模,不宜采用顺序表。
链表不需要事先估计存储规模,但存储密度较低(因为需要额外的指针空间)。
基于运算的考虑:
如果需要频繁按序号访问数据元素,顺序表优于链表。
如果需要频繁进行插入、删除等操作,链表优于顺序表。
基于环境的考虑:
顺序表基于数组,更容易实现,特别是在支持数组的编程语言中。
链表基于指针,可能在某些编程语言中实现起来较为复杂。
 

 

  • 4
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值