环形链表C/C++数据结构-创新互联
目录
信州网站建设公司创新互联公司,信州网站设计制作,有大型网站制作公司丰富经验。已为信州上1000+提供企业网站建设服务。企业网站搭建\外贸营销网站建设要多少钱,请找那个售后服务好的信州做网站的公司定做!什么是环?
例题 141. 环形链表
公式推导:
环形链表二 142. 环形链表 II
方法一:
方法二:
什么是环?类似这种,结点下一个指针又指向链表本身,这样若遍历链表的话则会变成死循环。
特殊情况:自己也有可能成环
环的特点:
有两个指针指向环的起点
判断是否有环
例题 141. 环形链表使用快慢指针,进入了环就变成了追及相遇的问题
思路:快指针一次走两步,慢指针一次走一步,当两个指针相遇时,即在链表中存在环
问题:为什么是快指针一次走两步?慢指针一次走一步?
bool hasCycle(struct ListNode *head) {
//判断空链表
if(!head){
return NULL;
}
struct ListNode *slow=head;
struct ListNode *fast=head;
//判断条件是什么?
//如果两个指针相等则有一个环
//就把它当作一个正常数组想
//因为只有这样才能从循环中出去
//判断条件怎么想?
while(fast&&fast->next)){
fast=fast->next->next;
slow=slow->next;
//要是环的话根本出不去
if(fast==slow){
return true;
}
}
return false;
}
公式推导:假设链表中无环
快指针走的距离=2*慢指针走到距离
假设链表中有环
进环前的距离L,环的长度C,环的开始点至相遇点的距离X
慢指针走过的距离:L+X
快指针走过的距离:L+C*N+X
由此可以得出一个等式
L+X=N*C
L=(N-1)*C+C-X
意思是在入环前的长度==环的长度-(开始点至相遇点的距离)
也就是说: 蓝色部分=L
环形链表二 方法一:本题首先需要找到相遇点,然后设立两个新的指针,两个指针从相遇点和起始点一起走,两个指针相遇的地方即为环形链表的起始点。
struct ListNode *detectCycle(struct ListNode *head) {
//L=C-X
//创立快慢指针
struct ListNode *slow=head;
struct ListNode *fast=head;
//确保fast没有空指针
while(fast&&fast->next){
//两者一起向前走
slow=slow->next;
fast=fast->next->next;
//找到相遇
if(slow==fast){
struct ListNode *meet=slow;
while(meet!=head){
//找到相遇点,两者一起走
meet=meet->next;
head=head->next;
}
//相遇,返回环的起始点
return meet;
}
}
return NULL;
}
方法二:使用相交链表的方式
先将链表从快慢指针的相遇点处断开
之后新建两个指针分别指向相遇点的下一位和原链表的头
利用相遇链表
相遇点即为起始点
struct ListNode *getIntersectionNode(struct ListNode *headA, struct ListNode *headB) {
//想一想,极端情况
//首先应该判断这两个链表不为空
if(!headA||!headB)
return NULL;
//找到两个链表的最后一个节点
struct ListNode *lastA=headA;
int numA=1;
while(lastA->next)
{
lastA=lastA->next;
numA++;
}
struct ListNode *lastB=headB;
int numB=1;
while(lastB->next)
{
lastB=lastB->next;
numB++;
}
//判断是否相交
//这就是找最后一个节点的作用
if(lastA!=lastB)
{
return NULL;
}
//找到长度,找最长的那个
//不是说不能倒着走吗?难道是要它倒叙?
//理解错了理解错了
struct ListNode *lenglist=headA;
struct ListNode *shortlist=headB;
if(numAnext;
}
//两个一起走
while(lenglist!=shortlist)
{
lenglist=lenglist->next;
shortlist=shortlist->next;
}
//走到不相等时分开,返回相交的节点
return lenglist;
}
struct ListNode *detectCycle(struct ListNode *head) {
//L=C-X
//创立快慢指针
struct ListNode *slow=head;
struct ListNode *fast=head;
//确保fast没有空指针
while(fast&&fast->next){
//两者一起向前走
slow=slow->next;
fast=fast->next->next;
//找到相遇
if(slow==fast){
struct ListNode *meet=slow;
struct ListNode*next=meet->next;
struct ListNode*walk=meet->next;
meet->next=NULL;
struct ListNode *newNode=getIntersectionNode(head,walk);
meet->next=next;
return newNode;
}
}
return NULL;
}
你是否还在寻找稳定的海外服务器提供商?创新互联www.cdcxhl.cn海外机房具备T级流量清洗系统配攻击溯源,准确流量调度确保服务器高可用性,企业级服务器适合批量采购,新人活动首月15元起,快前往官网查看详情吧
本文题目:环形链表C/C++数据结构-创新互联
分享地址:http://pwwzsj.com/article/dsshhd.html