【数据结构复习】链表相关
2013-10-06 11:53
309 查看
【数据结构复习】是学习、复习常用数据结构系列文章。数据结构与算法密不可分,是程序实现功能的重要组成部分。优秀的数据结构可以提高算法的时间及空间效率。反之,将增加算法复杂度,甚至妨碍程序的正确执行。
一、引言
链表是一种在存储空间上非连续的数据结构。每一个节点之间以指针连接,因此具有较大的灵活性。
二、基本构成与分类
1、基本构成
本节点的值(元素):
指向上节点的指针:
指向下节点的指针:
首节点:整条链表的第一个节点。取得它以后即可以遍历整条链表。
尾节点:通常以空指针NULL结尾,既是一个重要的判定标准,也是自己创建链表时常常易忘的一项。
2、分类
双向链表:普通包含上述全部成员的链表。
向后单向链表:每个节点只有指向下节点的指针。对于这类链表,首节点十分重要(因为无法回溯)。
向前单向链表:虽然出现得不多,但是难免有一些偏题怪题会提到。
三、基本操作
链表的基本操作实际上都指针操作,一定注意给涉及到的节点的“所有指针”安排好指向。常见错误是出现忘了赋值,仍然指向旧址,尾节点的下个指针不为NULL,头节点的上个指针不为NULL...
另一方面,链表的元素也可以操作,有时候链表结构无法更改时,通过元素互换达到目的(例如排序、无头节点时删除单向链表某节点)
1、插入
2、删除
四、双向链表问题收集(持续更新)
4.1、
五、单向链表问题收集(持续更新)
5.1、判断一个单向链表是否带环。
所谓带环,是指单向链表的一部分或全部处于循环之内。这是由于链表中有两个或以上节点的m_pNext指针指向了同一个节点。如图
解法:
创建两个指针,一个每次前进一步,记为pSlow,另一个每次前进两步,记为pFast。同时前进。如果两指针相遇,证明链表带环。如果至pFast到达链表尾都一直不相遇,证明无环。
5.2、判断链表是否相交。
分析:所谓相交,是指链表A和B有部分相同的节点。
解法:
首先要判断是否带环。
(1)如果两个链表都不带环,就判断尾节点是否相等,如相等则相交,如否则不相交。
(2)如果一个链表带环,另一个不带环。
(3)如果两个都带环。
5.3、不知道首节点,删除节点P
分析:由于首节点未知,无法取得节点P的前节点(设为Q)。如果直接删除P,Q->m_pNext将变成NULL,链表断裂。
解法:
5.4、求中央节点
解法:类似于5.1,一快一慢两指针,每次分别前进两步和一步。当pFast到达结尾,pSlow在中间。注意奇偶判断。
5.5、两有序链表,要求合并后仍然有序。
分析:以升序为例
解法1:递归解法
源码:
5.6、寻找倒数第k个节点
解法:
(1)生成两个指针pFast和pSlow。
(2)pFast先走k-1步。
(3)pFast和pSlow一同前进,当pFast到达尾结节点时,pSlow所指就是倒数第k个节点
补充:对于这种第k个节点的问题,事先还要判断节点个数是否有k个。
参考资料
http://blog.csdn.net/luxiaoxun/article/details/7538217 http://blog.csdn.net/xitijie/article/details/7639028 http://blog.csdn.net/yang6512/article/details/7393109
一、引言
链表是一种在存储空间上非连续的数据结构。每一个节点之间以指针连接,因此具有较大的灵活性。
二、基本构成与分类
1、基本构成
本节点的值(元素):
m_element
指向上节点的指针:
CNode* m_pPrev
指向下节点的指针:
CNode* m_pNext
首节点:整条链表的第一个节点。取得它以后即可以遍历整条链表。
firstNode { m_element; m_pPrev = NULL; // 关键 m_pNext; }
尾节点:通常以空指针NULL结尾,既是一个重要的判定标准,也是自己创建链表时常常易忘的一项。
lastNode { m_element; m_pPrev; m_pNext = NULL; // 关键 }
2、分类
双向链表:普通包含上述全部成员的链表。
template <typenema T> class CNode { T m_element; CNode* m_pPrev; CNode* m_pNext; }
向后单向链表:每个节点只有指向下节点的指针。对于这类链表,首节点十分重要(因为无法回溯)。
向前单向链表:虽然出现得不多,但是难免有一些偏题怪题会提到。
三、基本操作
链表的基本操作实际上都指针操作,一定注意给涉及到的节点的“所有指针”安排好指向。常见错误是出现忘了赋值,仍然指向旧址,尾节点的下个指针不为NULL,头节点的上个指针不为NULL...
另一方面,链表的元素也可以操作,有时候链表结构无法更改时,通过元素互换达到目的(例如排序、无头节点时删除单向链表某节点)
1、插入
2、删除
四、双向链表问题收集(持续更新)
4.1、
五、单向链表问题收集(持续更新)
5.1、判断一个单向链表是否带环。
所谓带环,是指单向链表的一部分或全部处于循环之内。这是由于链表中有两个或以上节点的m_pNext指针指向了同一个节点。如图
解法:
创建两个指针,一个每次前进一步,记为pSlow,另一个每次前进两步,记为pFast。同时前进。如果两指针相遇,证明链表带环。如果至pFast到达链表尾都一直不相遇,证明无环。
5.2、判断链表是否相交。
分析:所谓相交,是指链表A和B有部分相同的节点。
解法:
首先要判断是否带环。
(1)如果两个链表都不带环,就判断尾节点是否相等,如相等则相交,如否则不相交。
(2)如果一个链表带环,另一个不带环。
(3)如果两个都带环。
5.3、不知道首节点,删除节点P
分析:由于首节点未知,无法取得节点P的前节点(设为Q)。如果直接删除P,Q->m_pNext将变成NULL,链表断裂。
解法:
(1)设R = P->m_pNext // 取P的后节点R (2)P->m_element = R->m_element (3)删除节点R
5.4、求中央节点
解法:类似于5.1,一快一慢两指针,每次分别前进两步和一步。当pFast到达结尾,pSlow在中间。注意奇偶判断。
5.5、两有序链表,要求合并后仍然有序。
分析:以升序为例
解法1:递归解法
源码:
CNode* recursive_merge(CNode* a, CNode* b) { if(NULL == a) return b; if(NULL == b) return a; if(a->m_element < b->m_element) { a->m_pNext = recursive_merge(a->m_pNext, b); return a; } else { b->m_pNext = recursive_merge(a,b->m_pNext); return b; } }
5.6、寻找倒数第k个节点
解法:
(1)生成两个指针pFast和pSlow。
(2)pFast先走k-1步。
(3)pFast和pSlow一同前进,当pFast到达尾结节点时,pSlow所指就是倒数第k个节点
补充:对于这种第k个节点的问题,事先还要判断节点个数是否有k个。
参考资料
http://blog.csdn.net/luxiaoxun/article/details/7538217 http://blog.csdn.net/xitijie/article/details/7639028 http://blog.csdn.net/yang6512/article/details/7393109
相关文章推荐
- 对链表的相关操作及数据结构的再理解
- 链表的相关操作查找插入删除(c++ 数据结构)
- 对链表的相关操作及数据结构的再理解
- 关于数据结构的学习经验分享 (链表相关的内容)
- 一步一步复习数据结构和算法基础-链表(3)
- 《数据结构》复习之线性表(顺序表和链表)
- java数据结构链表,堆栈,队列相关专题分析与扯谈-链表
- C语言数据结构相关编程->链表001题
- 【数据结构】链表相关内容
- 数据结构复习 之 一个简单双向链表的实现
- 【链表复习】链表相关面试题
- java数据结构链表,堆栈,队列相关专题分析与扯谈-堆栈
- 数据结构-单链表相关面试题
- 【数据结构】链表及相关操作(C语言实现)
- 【数据结构】链表的原理及与其相关的常见面试题总结
- 复习四:链表——数据结构的的前奏之链表元素的遍历、删除以及链表中元素的删除
- 数据结构复习——线性表的链式存储实现(单向链表)
- 11-数据结构_链表相关操作
- 数据结构学习1:链表的相关操作
- java数据结构链表,堆栈,队列等相关专题分析与扯谈-队列