数据结构 | 再也不怕被问链表了

简介: 数据结构 | 再也不怕被问链表了

数组跟链表的区别:


首先,我们对比下数组跟链表的区别


内存分布区别:


1.数组在内存中的分配是连续的,对内存要求比较高

2.链表相反,它并不需要一块块连续的内存,它通过指针将一组零散的内存快串联起来使用


我们可以举个例子:当我们申请一个32M大小的内存,但是现在内存中没有一块连续的内存大于或等于32M的内存块,可以画图表示如下:

image.png

在这种情况下如果我们申请的数据结构是一个数组,那么内存的分配就会失败,反之如果我们申请的是一个链表的话就不会失败,因为链表的结构可以通过指针将这4个8M的内存块串联起来使用。


增删,查询的时间复杂度区别:


1.查询,数组时间复杂度为O(1),这里特指的是通过数组下标访问,不是指在数组中查询指定的值,具体可以参考我之前的文章:数据结构|数组为什么这么快?


链表的时间复杂度为O(n),如果我们需要在链表中访问一个元素,受链表底层数据结构的影响(不连续,通过指针串联)所以必须要一个个节点的遍历,不难得出时间复杂度为O(n)


2.增删,数组的增加或删除一个节点的时间复杂度为O(n),而链表的时间复杂度为O(1)。这里需要特别指出,我们在这里所说的增删特指单纯的删除动作。这是什么意思呢?大家可以看下面的

image.png

如果我们删除上图中下标为3的元素,对于数组而言,其实我们需要做的就是将4,5两个元素向前移动一个位置。所以对于数组删除的时间复杂度是没有影响的,O(n)。但是对于链表而言的话,我们需要先找到下标为2的这个元素,然后将下标为2的元素指向下标为4的元素。在查找下标为2的元素的这个过程中,我们知道链表的时间复杂度已经为O(n)了,虽然后面指针的断裂及再次指向下一个元素,时间复杂厚度为常量级,但是整个过程时间复杂为O(n)。所以我们下次在面试的时候就应该好好说清楚啦~


单链表:


如图所示就是一个单链表:

image.png

这里我们需要注意的主要是以下几点:


每个节点都保存了指向后一个节点的指针


1.头节点:链表就好比一条线,如果我们想捋清楚这条线,就一定要有一个线头,头节点2.就是这个线头,通过这个节点我们可以遍历整个链表,它记录了链表的基地址,及下一个元素的地址

3.尾节点:比较特殊的是,它指向了null


双链表:


图示如下:

image.png

我们可以跟单向链表做一个比较:


1.每个节点都保存了不仅仅是指向下一个节点的指针(后置指针),还有前一个元素的指针(前置指针)

2.头节点:保存了指向第二个元素的节点,前置指针指向null

3.尾节点:保存了指向倒数第二个元素的节点,后置指针指向null

到此,我们分析下相比于单向链表,双向链表用于解决什么问题呢?


我们对比单链表跟双链表的结构可以发现,双向链表可以支持O(1)的时间复杂度找到前置节点,正是这样的特点,也使得双向链表在某些情况下的插入,删除等操作都比单链表要高效。


我们可以分析这么一个场景,比如我们现在要删除一个给定指针指向的节点:

image.png

我们现在要删除p指针指向的节点,不管对于单链表还是双链表我们操作的步骤都是将Q指向M,同时将Q与P,P与M之间的链断掉。但是对于单链表而言,无法直接找到Q,因为没有保存一个指向上一个元素的指针,所以必须要从头遍历。而对于双向链表而言,P本身就保存了指向Q的一个前置指针。相比而言,双向链表的效率就大大提高了。


另外我们可以发现,双向链表由于比单链表多保存了一个指针,所以内存的消耗也会高于单链表


循环链表:


循环链表其实是一种特殊的单链表,与单链表不同的是,循环链表的尾指针不是指向null,而是指向头节点,图示如下:

image.png

与一般的单链表比较,循环链表最大的优点就是从链尾到链头比较方便。当处理的数据具有环形结构特点时,就特别适合采用循环链表。


总结:

到这里,我们已经对链表的各种情况都做了一个分析,也有了一个了解,但是单纯的知道它是什么是没有用的,我们可能更加知道这些数据结构能为我们做什么呢?所以下篇文章我们,我们将一起学习如何应用链表来解决我们的一些实际问题,包括缓存失效算法,约瑟夫问题等~


相关文章
|
1月前
|
缓存
数据结构之 - 链表数据结构详解: 从基础到实现
数据结构之 - 链表数据结构详解: 从基础到实现
72 6
|
17天前
|
存储 C语言
【数据结构】手把手教你单链表(c语言)(附源码)
本文介绍了单链表的基本概念、结构定义及其实现方法。单链表是一种内存地址不连续但逻辑顺序连续的数据结构,每个节点包含数据域和指针域。文章详细讲解了单链表的常见操作,如头插、尾插、头删、尾删、查找、指定位置插入和删除等,并提供了完整的C语言代码示例。通过学习单链表,可以更好地理解数据结构的底层逻辑,提高编程能力。
44 4
|
19天前
|
算法 安全 搜索推荐
2024重生之回溯数据结构与算法系列学习之单双链表精题详解(9)【无论是王道考研人还是IKUN都能包会的;不然别给我家鸽鸽丢脸好嘛?】
数据结构王道第2.3章之IKUN和I原达人之数据结构与算法系列学习x单双链表精题详解、数据结构、C++、排序算法、java、动态规划你个小黑子;这都学不会;能不能不要给我家鸽鸽丢脸啊~除了会黑我家鸽鸽还会干嘛?!!!
|
19天前
|
存储 Web App开发 算法
2024重生之回溯数据结构与算法系列学习之单双链表【无论是王道考研人还是IKUN都能包会的;不然别给我家鸽鸽丢脸好嘛?】
数据结构之单双链表按位、值查找;[前后]插入;删除指定节点;求表长、静态链表等代码及具体思路详解步骤;举例说明、注意点及常见报错问题所对应的解决方法
|
1月前
|
存储 Java
数据结构第三篇【链表的相关知识点一及在线OJ习题】
数据结构第三篇【链表的相关知识点一及在线OJ习题】
26 7
|
1月前
|
存储 安全 Java
【用Java学习数据结构系列】探索顺序表和链表的无尽秘密(附带练习唔)pro
【用Java学习数据结构系列】探索顺序表和链表的无尽秘密(附带练习唔)pro
23 3
|
1月前
|
算法 Java
数据结构与算法学习五:双链表的增、删、改、查
双链表的增、删、改、查操作及其Java实现,并通过实例演示了双向链表的优势和应用。
16 0
数据结构与算法学习五:双链表的增、删、改、查
|
17天前
|
C语言
【数据结构】双向带头循环链表(c语言)(附源码)
本文介绍了双向带头循环链表的概念和实现。双向带头循环链表具有三个关键点:双向、带头和循环。与单链表相比,它的头插、尾插、头删、尾删等操作的时间复杂度均为O(1),提高了运行效率。文章详细讲解了链表的结构定义、方法声明和实现,包括创建新节点、初始化、打印、判断是否为空、插入和删除节点等操作。最后提供了完整的代码示例。
38 0
【数据结构】——双向链表详细理解和实现
【数据结构】——双向链表详细理解和实现
|
1月前
|
存储 Java
【数据结构】链表
【数据结构】链表
18 1