zoukankan      html  css  js  c++  java
  • 转:有环链表交点判断

    http://blog.csdn.net/xie376450483/archive/2011/03/13/6247071.aspx

    今天要讲的和那篇类似,就是给定两个链表,如何来判断这两个链表相交了

    首先应该分两种情况考虑,第一:这两个链表本身都没有环。  第二:这两个链表本身都有环

    首先讲都没有环的情况,如下图

    方法很多,不过我想最简单的方法是遍历第一个链表,然后遍历到最后一个节点时候,用一个指针把节点地址记录下来

    然后再来遍历第二个链表,同样记录下最后一个链表的地址,如果两个指针的指向一样,那么就可以判断出两个链表相交了

    然后再来判断他们的交点

    把第一个链表的尾节点指向第二个链表的头结点,这样就形成了一个6字型的环链表,利用我们前面那篇文章讲的方法就可以求出相交节点

    然后说第二种情况

    两个链表本身都有环,首先我们应该知道如果一个链表有环,一个链表没有环,那么他们肯定不想交,自己画画图就明白了,不多说

    现在判断出两个链表都有环,那么怎么来判断相交了呢?

    方法是遍历利用前面的方法找到第一个链表的环点,然后将环断开(当然不要忘记了保存它的下一个节点),然后再来遍历第二个链表,如果发现第二个链表从有环变成了无环,那么他们就是相交的嘛,否则就是不相交的了。

    在判断出来两个有环的链表有交点后,然后来找出相交的节点,这时候又分了两种情况,相交点在环之前还是相交点在环之后,这样讲不严谨,应该是对一个链表来讲相交点是在另一个链表的环之前还是之后。

    方法如下

    首先找到两个链表的环点,利用前面那篇文章的方法,假设两个链表的环点分别是p1,p2 加入p1==p2 说明相交点是在环点之前,

    如下图:

    这时候我们可以从环点断开,同样记得保存下一个节点,然后把环点指向其中一个链表的表头,这样就把问题转换成前面6字形环形链表的相交节点问题

    如果两个链表的相交情况如下图呢?

    那这样就很那说哪个是交点了,因为有两个交点,其实不叫两个交点,是相对于l1来讲交点是l2的环点,相对于l2来讲交点是l1的环点

    而环点同样是前面的方法得到的。

      1. template<typename T>  
      2. ListNode<T>* FindFirstCommonNode_2(ListNode<T>* pHead1, ListNode<T>* pHead2)  
      3. {  
      4.     ListNode<T>* pEntrance1 = FindRingEntrance(pHead1);  
      5.     ListNode<T>* pEntrance2 = FindRingEntrance(pHead2);  
      6.   
      7.     ListNode<T>* pResult = NULL;  
      8.     if(pEntrance1 == pEntrance2)  
      9.     {  
      10.         ListNode<T>* pTemp1 = NULL, *pTemp2 = NULL;  
      11.         if(pEntrance1)  
      12.         {  
      13.             // 环入口点已经相交,寻找第一交点。  
      14.             pTemp1 = pEntrance1->pNext;  
      15.             pTemp2 = pEntrance2->pNext;  
      16.             pEntrance1->pNext = NULL;//断裂后变成两个单链表的方法来计算   
      17.             pEntrance2->pNext = NULL;  
      18.             pResult = FindFirstCommonNode(pHead1, pHead2);  
      19.             pEntrance1->pNext = pTemp1;  
      20.             pEntrance2->pNext = pTemp2;  
      21.         }  
      22.         else  
      23.         {  
      24.             // 无环单链表求第一交点  
      25.             pResult = FindFirstCommonNode(pHead1, pHead2);  
      26.         }  
      27.   
      28.         return pResult;  
      29.     }  
      30.     else if(pEntrance1 == NULL || pEntrance2 == NULL)  
      31.     {  
      32.         // 一有环,另一个无环,无交点  
      33.         return NULL;  
      34.     }  
      35.     else  
      36.     {  
      37.         // 入口点不同的两环求交点  
      38.         pResult = pEntrance1->pNext;  
      39.         while(pResult != pEntrance2 && pResult != pEntrance1)  
      40.         {  
      41.             pResult = pResult->pNext;  
      42.         }  
      43.           
      44.         return pResult == pEntrance2 ? pResult : NULL; //不确定两个环链表是否相交,否则两个环结点任一个都是结果  
      45.     }  
      46. }  
  • 相关阅读:
    Tomcat日志、项目中的log4j日志、e.printStackTrace()——我的日志最后到底跑哪去了?
    MySQL中有关TIMESTAMP和DATETIME的总结
    org.apache.ibatis.binding.BindingException: Invalid bound statement (not found)
    @RequestBody和@RequestParam区别
    Synchronized的jvm实现
    星空雅梦
    星空雅梦
    星空雅梦
    星空雅梦
    星空雅梦
  • 原文地址:https://www.cnblogs.com/xuhj001/p/3389162.html
Copyright © 2011-2022 走看看