数据结构之美-02-链表

75 阅读3分钟

数据结构之美-链表学习笔记

缓存是一种提高数据读取性能的技术,在硬件设计、软件开发中都有广泛的应用。缓存的大小有限制,当缓存被用满,那些数据应该清理,那些数据该暴露,这个需要缓存淘汰策略来决定,常见的策略有三种:先进先出(FIFO)、最少使用策略(LFO)、最近最少使用策略(LRU)。

上面的图中,数组需要一块连续的内存空间,如果内存没有连续 内存空间则会申请失败。

而链表却不会,他并不需要一块连续的内存空间,他通过“指针”将一组零散的内存块串联起来使用。

链表有多种结构,三种常见的结构:单链表、双向链表和循环链表。

单链表,单链表有一个头结点和一个尾节点,头节点用来记录链表的基地址,最后一个指向空的地方是链表的最后一个结点。

从图中可以看到这里的时间复杂度是O(1)

循环链表是一种特殊的单链表。跟单链表唯一的区别在尾节点,单链表的尾节点指向空指针,循环链表的尾结点指向链表的头结点。

单向链表只有一个方向,结点只有一个后继指针指向后面的结点,双向链表,支持2个方向,每个结点有next指针和pre指针指向前面的结点。

链表删除一个数据的情况: 1、删除结点中“值等于某个给定值”的结点 2、删除给定指针指向结点

第一种情况的时间复杂度,是o(1),遍历查找的时间是主要的耗时时间,时间复杂度是O(n)。所以删除的时间复杂度是O(n)。

第二种情况,双向链表的结点已经保存了前一个的指针,不需要再次遍历,因此时间复杂度是O(n)

思考题1、如何判断一个字符串是否是回文字符串,相对应的时间空间复杂度是多少?

回文字符串,是一个字符串正读反读都一样,比如“noon”这种的。如果字符串是通过单链表来存储的,如何进行判断?

答:使用快慢两个指针找到链表中点,慢指针每次前进一步,快指针每次前进两步。在慢指针前进的过程中,同时修改其 next 指针,使得链表前半部分反序。最后比较中点两侧的链表是否相等。

时间复杂度:O(n) 空间复杂度:O(n)

写链表代码技巧

1、理解指针或者引用的含义,将某个变量赋值给指针,实际上就是将这个变量的地址赋值给指针,或者反过来说,指针中存储了这个变量的内存地址,只想了这个变量,通过指针就能找到这个变量。

2、警惕指针丢失和内存泄漏,插入结点时,一定要注意操作的顺序。删除链表结点的时候,也一定要记得手动释放内存空间。

3、利用哨兵简化实现难度。针对链表的插入,删除操作,需要对插入第一个结点和删除最后一个结点的情况进行特殊处理。

4、重点留意边界条件处理, (1)如果链表为空,代码能否正常工作

(2)如果链表只包含一个结点,代码是否能正常工作

(3)如果链表只包含两个结点时,代码是否能正常工作

(4)代码逻辑在处理头结点和尾结点的时候,能否正常工作

5、举例画图,辅助思考

熟练以下5种链表的代码

单链表反转

链表中环的检测

两个有序的链表合并

删除链表倒数第n 个结点

求链表的中间结点