标签:
第7题
微软亚院之编程
判断俩个链表是否相交
给出俩个单向链表的头指针,比如h1,h2,判断这俩个链表是否相交。
为了简化问题,我们假设俩个链表均不带环。
问题扩展:
1.如果链表可能有环列?
2.如果需要求出俩个链表相交的第一个节点列?
思路:
判断两个链表是否相交,并且求第一个节点列(无环)。
利用计数
如果两个链表相交,两个链表就会有共同的结点列;统计链表的长度,求两个链表长度差(目的是将两个链表变成到末尾长度相同的两个链表,相交部分一定在里面),然后往后遍历,找到相等的结点,就是第一个结点。
判断是否有环
2s = s + nr
s= nr
设整个链表长L,入口环与相遇点距离为x,起点到环入口点的距离为a。
a + x = nr
a + x = (n – 1)r +r = (n-1)r + L - a
a = (n-1)r + (L – a – x)
#include<cstdio> #include<malloc.h> #include<iostream> using namespace std; struct node{ int m_nValue; List *next; }; void InsertList(node *&head,int value){ if(head==NULL){ List *m_pList=new List(); if(m_pList==NULL){ cout<<"insufficient memory.\n"; return; } m_pList->m_nValue=value; m_pList->next=NULL; head=m_pList; }else InsertList(head->next,value); }
//查找相交点 node* FindNode(node *head1,node *head2){ if(head1==NULL||head2==NULL) return NULL;//如果为空,一定不能相交 node *p1,*p2; p1=head1;p2=head2; int len1=0,len2=0; int diff=0;//通过计数法统计他们的长度差 while(p1->next!=NULL){ p1=p1->next;len1++; } while(p2->next!=NULL){ p2=p2->next;len2++; } if(p1!=p2) return NULL;//最后一个结点不同,肯定不相交 diff=len1>len2?len1-len2:len2-len1; if(len1>len2){p1=head1;p2=head2;} else {p1=head2;p2=head1;} for(int i=0;i<diff;i++) p1=p1->next; while(p1!=p2){ p1=p1->next;p2=p2->next; } return p2; } node* HasLoop(node *head){ bool hasLoop = false; node *fast,*slow;//利用快慢指针 fast=head;slow=head; while(fast&&fast->next){ slow=slow->next; fast=fast->next->next;//fast每次走两步,slow每次走一步 if(fast==slow){//当两指针相遇,说明有环 hasLoop =true; break; } } if(hasLoop){//有环时我们找入环的第一个结点 slow=head; while(slow!=fast){ slow=slow->next; fast=fast->next; }
//可以将链表的分解函数在这里调用。将slow设为标志,无环的新链表为表头到slow。slow->next=NULL;
return slow;
}else return NULL; }
标签:
原文地址:http://www.cnblogs.com/wabi87547568/p/5262926.html