链表的一些典型问题

求链表的中间节点/倒数第K个节点

等类似的随机访问,可以考虑用快慢指针

 

求链表的中间节点

可以定义两个指针,一个一次走两步一个一次走一步,当走的快的走到NULL时,走的慢的就是链表的中间节点。(此法求出的偶数个节点的链表的中间节点是它中间的第二个)

 

求倒数第K个节点,也可以定义两个指针,然后一个先走K步,走完以后,另一个再走


判断是否为回文链表

 

先用快慢指针求中间节点

逆置中间节点及其后的节点,并用一个指针指向该逆置后的链表

头指针和指向该逆置后的链表的指针一起走并比较是否相等,有一个不相等就不是回文链表

有一个链表走到NULL就停下,并且该链表是回文链表(因为中间节点的前一个结点还指向逆置后的最后一个节点)


 

判断两个链表是否相交,并且求出第一个相交的节点

如果相交这两个链表的尾节点一定相等

如果两个链表的尾节点相等,就求出两个链表的长度

让长的先走这两个链表长度的差值步,然后一起走

走到两个链表的节点的指针域第1次相等的地方,就是第一个相交的节点


判断链表是否带环

(用快慢指针,一个走一次走两步,一个一次走一步)

 

由于快指针与慢指针走的步数差为1(步数差=快指针一次走的步数—慢指针一次走的步数),所以如果链表带环,慢指针最终一定会追上快指针,反之则不会。

 

如果快指针与慢指针走的步数差为1(步数差=快指针一次走的步数—慢指针一次走的步数)则快慢指针一定会再环中相遇

 

因为

则设快指针入和慢指针入环后的差距为N,

如果快指针与慢指针走的步数差为1

那么他们两个指针每走一次,N就减1,当N为0时就相遇了

 

如果快指针与慢指针走的步数差不为1

就要看N是不是他们两个的差值的倍数了,

 

如果不是就要看N减到负数时新的N是不是他们两个都倍数,如果还不是,就肯定追不上了。

 


求带环链表的入环节点

 

结论:快指针从相遇点开始走,慢指从链表的头开始走,他们会在环的入口点相遇

链表的一些典型问题_第1张图片

 

把快慢指针的相遇点指向NULL,让一个新的指针指向相遇点的下一个节点,让这个新的指针一步一步向后走,再让一个指针原链表的头开始走,这两个链表的交点就是链表入环点


复制复杂链表问题

(复杂链表是多了一个随机指针,这个指针可能指向他自己这个链表的任何一个节点,也可能指向NULL)

 

时间复杂度为O(N)的方法

 

在原链表的每一个节点后面插入malloc一个新节点,这个新节点复制了它前一个节点的数据域。

 

这个新节点的随机指针指向它前一个节点的随机指针指向的节点的next,如下图

链表的一些典型问题_第2张图片

最后把新的malloc出来的节点连接起来,再把原链表恢复 

你可能感兴趣的:(c语言)