关于单链表的几个问题
2012-06-18 13:44
288 查看
Q:如何判断一个单链表是否有环,如果有环,找出环的入口点?
A:首先我们判断链表是否有环,设置两个指针slow和fast,指向单链表的头部,每个循环slow走一步,fast走两步。如果没有环,fast或者fast的next会走到NULL,否则fast在环里循环最终会和slow相遇,此时即存在环。
再看第二个问题,当slow和fast相遇时,假设fast已经在环内循环n圈,环长为r,同时fast走的长度为slow走的长度的两倍,设slow走了s步,则有
2*s=s+n*r => s=n*r,再设单链表头部到环入口的距离为a,环入口到相遇点得距离为x,则a+x=s=n*r,因此从单链表头部到相遇点的距离为环长的整数倍,因此我们可以将slow或fast指向单链表头部,和另外一个指针每次一步往前走,则再次相遇时他们同时指向的就是环的入口点。
Q:找出两个单链表的第一个公共结点。
A:
方法1:将第一个单链表首尾连接,判断第二个单链表有没有环,如果有则说明两个单链表相交,此时可以求出第二个单链表的环入口结点,即为第一个公共结点。
方法2:如果两个单链表相交,则他们从第一个公共结点到最后一个结点肯定都相同,此时求出两个单链表的长度lenA和lenB,假设lenA>lenB,则将指向A链表头的指针先前进(lenA-lenB)步,而指向B链表的指针此时还指向B链表头,然后再将两个链表每次各走一步,则相遇就在第一个公共结点。
A:首先我们判断链表是否有环,设置两个指针slow和fast,指向单链表的头部,每个循环slow走一步,fast走两步。如果没有环,fast或者fast的next会走到NULL,否则fast在环里循环最终会和slow相遇,此时即存在环。
再看第二个问题,当slow和fast相遇时,假设fast已经在环内循环n圈,环长为r,同时fast走的长度为slow走的长度的两倍,设slow走了s步,则有
2*s=s+n*r => s=n*r,再设单链表头部到环入口的距离为a,环入口到相遇点得距离为x,则a+x=s=n*r,因此从单链表头部到相遇点的距离为环长的整数倍,因此我们可以将slow或fast指向单链表头部,和另外一个指针每次一步往前走,则再次相遇时他们同时指向的就是环的入口点。
struct Node { int value; Node* next; }; Node* FindLoopEntrance(Node* head) { Node *slow,*fast; slow=head; fast=head; while(fast && fast->next) { slow=slow->next; fast=fast->next->next; if(slow==fast) break; } //无环 if(!fast || !fast->next) return NULL; slow=head; while(slow!=fast) { slow=slow->next; fast=fast->next; } return slow; }
Q:找出两个单链表的第一个公共结点。
A:
方法1:将第一个单链表首尾连接,判断第二个单链表有没有环,如果有则说明两个单链表相交,此时可以求出第二个单链表的环入口结点,即为第一个公共结点。
方法2:如果两个单链表相交,则他们从第一个公共结点到最后一个结点肯定都相同,此时求出两个单链表的长度lenA和lenB,假设lenA>lenB,则将指向A链表头的指针先前进(lenA-lenB)步,而指向B链表的指针此时还指向B链表头,然后再将两个链表每次各走一步,则相遇就在第一个公共结点。
相关文章推荐
- 关于单链表的几个有意思的问题
- 基本数据结构——关于单链表相交的几个问题
- 关于几个字符集问题
- 关于phpstudy中使用composer的几个问题
- Android几个关于Gesture的问题
- 关于光纤通道存储交换机的几个问题
- 面试中可能会被问到的几个关于“委托”的问题
- 关于产品的几个问题分析(来自京东产品经理笔试题)
- 关于Service中bindService注意的几个问题
- 关于C和C++动态链接库的几个问题
- 做项目时遇到的几个关于C#和SQL的细节问题(二)
- 纠结了好几个小时关于在标识符前缺少;的问题
- 关于输入scanf()中缓冲区的几个问题
- 今日的问题:关于java.util包的几个问题?
- 关于支付宝需要注意的几个问题。
- 关于Segmentation fault (core dumped)几个简单问题的整理
- 关于几个指针的问题
- 关于N!的几个问题
- 关于char占几个字节的问题如下
- 关于<img>标签的几个问题