链表带环问题1

来源:互联网 发布:js获取tr的第一个td 编辑:程序博客网 时间:2024/04/27 21:38

给出一个链表;

1.判断其是否带环?

2.如果带环求环的长度?

3.求环的入口节点?

解题思路:

用两个指针,快指针一次走两步,慢指针一次走一步,如果两指针相遇,那么链表带环,若两指针不相遇,则链表不带环。

带环的几种情况:


Node* List::find_meet_node(Node* Head){if(Head==NULL)return NULL;if(Head->_next ==Head)return Head;Node* entry=NULL;Node* fast=Head;Node* slow=Head;while(fast){fast=fast->_next ->_next ;slow=slow->_next ;if(fast==slow)return fast;}return NULL;}void List::IsHasRing(Node* Head){Node* ret=find_meet_node(Head);if(ret==NULL)cout<<"no ring"<<endl;elsecout<<"have a ring"<<endl;}



2.求环的长度:

解题思路:

面试题1已经判断过链表带环,且返回两指针相遇节点,求环长度时我们可以让一个指针从相遇节点处开始遍历,当再次回到相遇节点时,它走过的步数就是环的长度。

int List::ring_len(Node* meet){if(meet==NULL)return 0;Node* cur=meet->_next ;int len=1;while(cur!=meet){cur=cur->_next;    len++;}return len;}


3.求环的入口节点:

方法一:假设上图是一个单链表,两指针走到相遇节点时,慢指针走了L+X步,快指针走了L+X+nC步,(l为环的长度),由于快指针速度是慢指针速度的一倍,那么就有以下的等式:
(L+X)*2=L+X+nC;化解可得:L=nC-X;

那解题时我们可以用两个指针,一个指针从链表的开始位置走,另一个指针从相遇的节点处开始走,也就是y,两个指针相遇的节点就是入口点。


Node* List::find_entry(Node* Head,Node* meet){if(meet==NULL)return NULL;Node* prev=Head;Node* post=meet;while(prev!=post){prev=prev->_next ;post=post->_next ;}return prev;}

方法二:将相遇的节点处断开,转化为两条链表相交求交点问题,两个指针meet和Entry分别遍历到链表尾,记录两链表的长度len_l1和len_l2,然后让较长的链表先走len=|len_l1 - len_l2|步,然后两指针一起走,直到两指针相遇,相遇的节点就是链表的交点,即环的入口点。


Node* List::find_entry(Node* Head,Node* meet){ pLinkNode Entry = head; pLinkNode meet = MeetNode->next; int len_head = 0; int len_meet = 0; int len = 0; while (Entry != MeetNode) //求链表长度 {  len_head++;  Entry = Entry->next; } while (meet != MeetNode)//求链表长度 {  len_meet++;  meet = meet->next; }  Entry = head;  meet = MeetNode->next; if (len_head > len_meet)   {  len = len_head - len_meet;  while (len--)  {   Entry = Entry->next;  }//较长链表先走len=|len_l1 - len_l2|步 } else {  len = len_meet - len_head;  while (len--)  {   meet = meet->next;  }//较长链表先走len=|len_l1 - len_l2|步 } while (meet != Entry) {  Entry = Entry->next;  meet = meet->next; } //两指针同时走,相遇节点就是环入口点 return Entry;}



测试运行结果:

测试用例:

void test3()//测试是否带环{List l;Node* node1=new Node(0);Node* node2=new Node(1);Node* node3=new Node(2);Node* node4=new Node(3);Node* node5=new Node(4);Node* node6=new Node(5);Node* node7=new Node(6);node1->_next =node2;node2->_next =node3;node3->_next =node4;   node4->_next =node5;node5->_next =node6;node6->_next =node5;    l.IsHasRing(node1);Node* meet=l.find_meet_node(node1);cout<<"meet:"<<meet->_data <<endl;int len=l.ring_len(meet);cout<<"length:"<<len<<endl;Node* entry=l.find_entry(node1,meet);cout<<"entry:"<<entry->_data <<endl;}

运行结果:


到此结束!









原创粉丝点击