编程判断两个链表是否相交
2015-01-11 19:41
232 查看
《编程之美》3.6节:判断两个链表是否相交
问题:给出两个单项链表的头指针,判断这两个链表是否相交,假设都不带环。
解法:遍历第一个链表至尾节点,然后遍历第二个链表,如果尾节点和刚才相同,则说明相交,否则不想交。
代码:
扩展问题一:如果链表可能有环,上面代码如何修改?
解法:先找出第一个链表的环的入口节点first,然后找出第二个链表的环的入口节点second,如果相同,则肯定相交。如果不相同则令curr=second->next,然后curr!=second,即遍历一遍第二个链表的环,如果有curr==first,则证明相交,否则不想交。
扩展问题二:求出两个链表相交的第一个节点?
解法:分两种情况,一种是没有环,两链表相交,把链表尾节点的下一个节点指向第二个链表的头结点,那么这个问题便转换成了求一个带环链表的环的入口节点。第二种情况是两链表有环且相交,此时求出两个链表分别的环的入口节点first和second,如果不相同则第二个链表的入口节点就是所求;如果相同,则把first->next=nullptr,即把链表的环断开,然后根据无环的相交链表求相交的节点即可,即情况一。
代码:
问题:给出两个单项链表的头指针,判断这两个链表是否相交,假设都不带环。
解法:遍历第一个链表至尾节点,然后遍历第二个链表,如果尾节点和刚才相同,则说明相交,否则不想交。
代码:
#include<iostream> using namespace std; struct Node { Node *next; int data; Node(int d=0,Node *n=NULL):next(n),data(d){} }; bool isCrossList(Node *firstList,Node *secondList) { if(firstList==nullptr || secondList==nullptr) return false; Node *curr=firstList; while(curr->next!=nullptr) curr=curr->next; Node *tail=curr; curr=secondList; while(curr->next!=nullptr) curr=curr->next; if(curr==tail) return true; else return false; } int main() { Node *firstList=new Node(0); Node *cross; Node *curr=firstList; for(int i=1;i<10;i++) { curr->next=new Node(i); if(i==5) cross=curr->next; curr=curr->next; } Node *secondList=new Node(0); curr=secondList; for(int i=1;i<5;i++) { curr->next=new Node(i); curr=curr->next; } curr->next=cross; bool result=isCrossList(firstList,secondList); cout<<result<<endl; system("pause"); return 0; }
扩展问题一:如果链表可能有环,上面代码如何修改?
解法:先找出第一个链表的环的入口节点first,然后找出第二个链表的环的入口节点second,如果相同,则肯定相交。如果不相同则令curr=second->next,然后curr!=second,即遍历一遍第二个链表的环,如果有curr==first,则证明相交,否则不想交。
扩展问题二:求出两个链表相交的第一个节点?
解法:分两种情况,一种是没有环,两链表相交,把链表尾节点的下一个节点指向第二个链表的头结点,那么这个问题便转换成了求一个带环链表的环的入口节点。第二种情况是两链表有环且相交,此时求出两个链表分别的环的入口节点first和second,如果不相同则第二个链表的入口节点就是所求;如果相同,则把first->next=nullptr,即把链表的环断开,然后根据无环的相交链表求相交的节点即可,即情况一。
代码:
#include<iostream> using namespace std; struct Node { Node *next; int data; Node(int d=0,Node *n=NULL):next(n),data(d){} }; bool hasLoop(Node *head) { if(head==nullptr || head->next==nullptr) return false; Node *slow=head->next; Node *fast=head->next->next; while(fast!=nullptr && fast->next!=nullptr) { if(fast==slow) return true; slow=slow->next; fast=fast->next->next; } return false; } Node * firstCrossNode(Node *head) { Node *slow=head->next; Node *fast=head->next->next; while(fast!=nullptr && fast->next!=nullptr) { if(fast==slow) { slow=head; break; } slow=slow->next; fast=fast->next->next; } while(slow!=fast) { slow=slow->next; fast=fast->next; } return slow; } bool isCrossListNoLoop(Node *firstList,Node *secondList) { if(firstList==nullptr || secondList==nullptr) return false; Node *curr=firstList; while(curr->next!=nullptr) curr=curr->next; Node *tail=curr; curr=secondList; while(curr->next!=nullptr) curr=curr->next; if(curr==tail) return true; else return false; } bool isCrossListHasLoop(Node *firstList,Node *secondList) { Node *first=firstCrossNode(firstList); Node *second=firstCrossNode(secondList); if(first==second) return true; Node *curr=second->next; while(curr!=second)//只需要判断这两个环是不是一个环就行了 { if(curr==first) return true; curr=curr->next; } return false; } bool isCrossList(Node *firstList,Node *secondList) { bool firstLoop=hasLoop(firstList),secondLoop=hasLoop(secondList); if(firstLoop && !secondLoop)//第一个有环第二个没环,肯定不相交 return false; else if(firstLoop)//如果都有环 return isCrossListHasLoop(firstList,secondList); else//如果两个都没环,调用常规程序解即可 return isCrossListNoLoop(firstList,secondList); } Node *twoListFirstCrossNodeNoLoop(Node *firstList,Node *secondList) { Node *curr=secondList; while(curr->next!=nullptr) curr=curr->next; Node *tail=curr; tail->next=secondList; Node *firstCross=firstCrossNode(firstList); tail->next=nullptr; return firstCross; } Node *twoListFirstCrossNodeHasLoop(Node *firstList,Node *secondList) { Node *first=firstCrossNode(firstList); Node *second=firstCrossNode(secondList); if(first!=second)//返回secondList接入firstList的第一个节点 return second; else//如果first==second则有两种情况:一是两个链表在第一个链表环的入口处相交,另一种情况是在环的外面相交 { //不论是哪种情况,都需要在链表入口的地方拆断链表,然后按没有环的情况处理即可 Node *temp=first->next; first->next=nullptr; Node *result=twoListFirstCrossNodeNoLoop(firstList,secondList); first->next=temp; return result; } } Node *twoListFirstCrossNode(Node *firstList,Node *secondList) { if(!isCrossList(firstList,secondList))//如果不相交 return nullptr; bool firstLoop=hasLoop(firstList);//如果相交,那么两个链同时有环或者无环 if(firstLoop==false)//如果无环 return twoListFirstCrossNodeNoLoop(firstList,secondList); else return twoListFirstCrossNodeHasLoop(firstList,secondList); } int main() { Node *firstList=new Node(0); Node *cross; Node *curr=firstList; for(int i=1;i<10;i++) { curr->next=new Node(i); if(i==5) cross=curr->next; curr=curr->next; } curr->next=cross->next->next; Node *secondList=new Node(0); curr=secondList; for(int i=1;i<5;i++) { curr->next=new Node(i); curr=curr->next; } curr->next=cross; bool result=isCrossList(firstList,secondList); cout<<result<<endl; cout<<twoListFirstCrossNode(firstList,secondList)->data<<endl; system("pause"); return 0; }
相关文章推荐
- 编程之美3.6——编程判断两个链表是否相交
- 编程判断两个链表是否相交 结构之法 6
- 编程之美--3.6编程判断两个链表是否相交
- 读书笔记之编程之美 - 3.6 编程判断两个链表是否相交
- 编程之美3.6—判断两个链表是否相交
- 编程之美:编程判断两个链表是否相交
- 编程之美-编程判断两个链表(可能含环)是否相交以及相交的第一个结点
- 编程之美-3.6-编程判断两个链表是否相交
- 3.6 编程判断两个链表是否相交
- 编程判断两个链表是否相交
- 编程判断两个链表是否相交
- 编程之美-3.6-编程判断两个链表是否相交
- 编程判断两个链表是否相交
- 《编程之美》——编程判断两个链表是否相交
- 判断两个链表是否相交(在线编程测试平台www.anycodex.com)
- 编程之美-3.6-编程判断两个链表是否相交
- 【编程之美】3.6 - 判断两个链表是否相交
- 编程之美---判断两个链表是否相交
- 编程之美-判断两个链表是否相交方法整理
- 单链表之编程判断两个链表是否相交