zoukankan      html  css  js  c++  java
  • 如何判断两个单向链表是否有相交,并找出交点

    转载:http://blog.chinaunix.net/uid-20754793-id-177773.html

    判断两个链表是否相交:(假设两个链表都没有环)
    1、判断第一个链表的每个节点是否在第二个链表中
    2、把第二个链表连接到第一个后面,判断得到的链表是否有环,有环则相交
    3、先遍历第一个链表,记住最后一个节点,再遍历第二个链表,得到最后一个节点时和第一个链表的最后一个节点做比较,如果相同,则相交

    如何判断一个单链表是有环的?(注意不能用标志位,最多只能用两个额外指针)
    一种O(n)的办法就是(用两个指针,一个每次递增一步,一个每次递增两步,如果有环的话两者必然重合,反之亦然):
    bool check(const node* head)
    {
        if(head==NULL) return false;
        node *low=head, *fast=head->next;
        while(fast!=NULL && fast->next!=NULL)
        {
            low=low->next;
            fast=fast->next->next;
            if(low==fast) return true;
        }
        return false;
    }

    扩展问题参考:http://hi.baidu.com/azuryy/blog/item/18e85b02ec34a4094bfb51de.html
    扩展1:如果链表可能有环,则如何判断两个链表是否相交
    思路:链表1 步长为1, 链表2步长为2 ,如果有环且相交则肯定相遇,否则不相交

    list1 head: p1
    list2 head: p2
    while( p1 != p2 && p1 != NULL && p2 != NULL )
    {

          p1 = p1->next;
          if ( p2->next )
             p2 = p2->next->next;
          else
             p2 = p2->next;
    }
    if ( p1 == p2 && p1 && p2) //相交
    else //不相交

    扩展2:求两个链表相交的第一个节点
    思路:在判断是否相交的过程中要分别遍历两个链表,同时记录下各自长度。

    Node* step( Node* p, Node* q)
    {
        if ( !p || !q ) return NULL;
        int pLen = 1;
        int qLen = 1;
        bool result = false;
        while( p->next )
        {
            pLen++, p = p->next;
        }
        while( q->next )
        {
            qLen++, q = q->next;
        }
        result = ( p == q );
        if ( result )
        {
            int steps = abs( pLen - qLen);
            Node* head = pLen > qLen ? p : q;
            while ( steps ) //对齐处理
            {
                    head = head->next, steps--;
            }
            pLen > qLen ? p = head : q = head;
            while ( p != q )
            {
                    p = p->next, q = q->next;
            }
            reutrn p;
        }
        return NULL;
    }
    下面转载来源:
    http://blog.chinaunix.net/u2/63031/showart_1003241.html

    深信服一道笔试:如何判断两个单向链表是否有相交,并找出交点。

    题比较简单,单向链表有交点意思就是交点后的节点都是一样的了。

    NODE* FindNode(NODE* pHead1, NODE* pHead2)
    {
        NODE* p1 = pHead1;
        NODE* p2 = pHead2;
        int i = 1, j = 1, k = 0, f = 0;

        if(pHead2 == NULL || pHead2 == NULL)
        {
            return NULL;
        }

        while(p1->next != NULL)
        {
            p1 = p1->next;
            i++;
        }

        while(p2->next != NULL)
        {
            p2 = p2->next;
            j++;
        }

        if(p1 != p2)
        {
            return NULL;
        }
        else
        {
            p1 = pHead1;                // 1
            p2 = pHead2;

            f = fabs(i, j);
            if(i > j)                    // 2
            {
                for(k=0; k<f; k++)
                {
                    p1 = p1->next;
                }
                while(p1 != p2)
                {
                    p1 = p1->next;
                    p2 = p2->next;
                }
                return p1;
            }
            else
            {
                for(k=0; k<f; k++)
                {
                    p2 = p2->next;
                }
                while(p1 != p2)
                {
                    p1 = p1->next;
                    p2 = p2->next;
                }
                return p1;
            }
        }
    }

    1,在第一次遍历完链表后,进行第二次遍历,需要把指针再次初始化;看见网上一些人给的例子没有再次初始化显然是错误的;再调用NULL的next不死才怪!

    2,小优化。循环和判断,把判断放在外面;如果把i和j大小判断放在里面的话就意味着循环多少次,判断就执行多少次;当然这样做的唯一不足就是代码 多了点;还有for循环之前的对f的赋值,有的为了简便直接放在for语句里面,不过同样道理,放在for循环里面,就执行了n次的fabs;拿出来赋 值,只赋值一次就OK。

    友情提示:养成写高效代码的习惯,不能图简便,觉得代码越少就越牛!

  • 相关阅读:
    Apple Watch知识点总结
    segue场景跳转的使用总结
    iOS地图相关知识点总结
    第三方库AFNetwork的作用和用法详解
    UIImagePickerController的知识点总结
    关于图片的压缩问题
    盒子模型知识
    CSS3新增属性
    ps命令详解
    http请求中的Referer的作用
  • 原文地址:https://www.cnblogs.com/pengdonglin137/p/3615463.html
Copyright © 2011-2022 走看看