判断两链表是否相交,如果相交找到第一个交点

#include <stdio.h>
#include <stdlib.h>
typedef struct LinkNode
{
    struct LinkNode* next;
    int data;
}LinkList;
/*说明:都带头结点的单链表*/
/*创建链表*/
void createLinkList(LinkList* head, int* a, int n)
{
    int i = 0;
    LinkNode* node = NULL;
    while (i < n)
    {
        node = new LinkNode;
        node->next =  head->next;
        node->data = a[i];
        head->next = node;
        i++;
    }
}
/*获取链表的长度*/
int getLenOfList(LinkList* head)
{
   int i = 0;
   LinkNode* node = head;

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

   return i;
}
/*获取链表的第K个节点*/
LinkNode* getKNode(LinkList* head, int K)
{
    LinkNode* p = head;

    while ((p->next!=NULL) && (K>0))
    {
        p = p->next;
        K--;
    }

    return (K>0) ? NULL:p;
}
/*注意此函数找不带环的链表,如果带环需要重新考虑*/
/*参考:http://blog.csdn.net/xiaodeyu2010xiao/article/details/42460203*/
/*备注:改博客应该遗漏还有一种情况,在成环的情况下,如果是如下情况的处理:
链表A:
O->O->O->O->O-->
   ^     ^      |
   |     |      |
   |      ------|
   |
   <----O<-O<-O<-O :链表B

方法其实很类似:判断是否成环,找到成环结点是否相同,如果相同的话,
则按照不想交的判断,取两链表长度,让长的先走N-M(N,M分别是两链表的长度)
然后同时向前走,如果结点相等且不是环结点退出,找到相交的第一个结点
*/
/*说明:改函数可以继续优化,如果根本就不想交直接判断最后一个结点是否相等退出*/
bool findFirstCommonNode(LinkList* l, LinkList*s,  LinkNode* &node)
{
    int n = getLenOfList(l);/*获取链表长度*/
    int m = getLenOfList(s);/*获取链表长度*/
    LinkNode* p;
    LinkNode* q;

    /*分别找到起点*/
    if (n > m)
    {
       p = getKNode(l, n-m);
       q = s;
    }
    else
    {
        p = getKNode(s, m-n);
        q = l;
    }

    /*往下走找到起点*/
    while (p!=NULL && q!=NULL)
    {
        if (p == q)
        {
            node = p;
            return true;
        }
        p = p->next;
        q = q->next;
    }
    return false;
}
/*将s链表尾节点添加到l链表的K个位置*/
bool appendKNode(LinkList* l, LinkList* s, int K)
{
      LinkNode* lastNode = s;
      LinkNode* node = l;

      while (lastNode->next != NULL)
      {
          lastNode = lastNode->next;
      }

      while (node->next!=NULL && (K>0))
      {
          node = node->next;
          K--;
      }

      if (K > 0)
      {
          return false;
      }

      lastNode->next = node;
      return true;
}
/*打印链表*/
void printLinkList(LinkList* head)
{
    LinkNode* node = head->next;
    while (node != NULL)
    {
        printf("%d\t", node->data);
        node = node->next;
    }
    printf("\n");
}
int main()
{
    /*创建链表*/
    LinkList l = {0};
    LinkNode* node = NULL;
    int a[] = {9, 8, 7, 6, 5, 4, 3, 2, 1};
    createLinkList(&l, a, 9);
    printLinkList(&l);

    /*创建链表*/
    LinkList s = {0};
    int b[] = {15, 14, 13, 12};
    createLinkList(&s, b, 4);
    printLinkList(&s);

    findFirstCommonNode(&l, &s, node);
    if (node != NULL)
    {
        printf("first common node %d\n", node->data);
    }
    else
    {
        printf("NO COMMON NODE\n");
    }
    /*将s链表尾节点添加到l链表的K个位置*/
    appendKNode(&l, &s, 3);
    printLinkList(&s);
    findFirstCommonNode(&l, &s, node);
    if (node != NULL)
    {
        printf("first common node %d\n", node->data);
    }
    return 0;
}

时间: 2024-10-07 05:02:25

判断两链表是否相交,如果相交找到第一个交点的相关文章

7_2判断两个单链表是否相交,若相交,求出第一个交点

转载请注明出处:http://www.cnblogs.com/wuzetiandaren/p/4251372.html 声明:现大部分文章为寻找问题时在网上相互转载,此博是为自己做个记录记录,方便自己也方便有类似问题的朋友,本文的思想也许有所借鉴,但源码均为本人实现,如有侵权,请发邮件表明文章和原出处地址,我一定在文章中注明.谢谢. 题目:7_2判断两个单链表是否相交,若相交,求出第一个交点. 题目分析: 创建A,B两个单链表,将B的尾部指向头部,若两个单链表相交,则交点必为环的入口,这就又变成

如何判断单链表是否存在环 &amp; 判断两链表是否相交

给定一个单链表,只给出头指针h: 1.如何判断是否存在环? 2.如何知道环的长度? 3.如何找出环的连接点在哪里? 4.带环链表的长度是多少? 解法: 1.对于问题1,使用追赶的方法,设定两个指针slow.fast,从头指针开始,每次分别前进1步.2步.如存在环,则两者相遇:如不存在环,fast遇到NULL退出. 2.对于问题2,记录下问题1的碰撞点p,slow.fast从该点开始,再次碰撞所走过的操作数就是环的长度s. 3.问题3:有定理:碰撞点p到连接点的距离=头指针到连接点的距离,因此,分

Solution 7: 判断两链表是否相交

问题描述 RT. 解决思路 (1) 两链表都是单向链表:判断两链表的末尾节点是否相同: (2) 两链表中一个有环,一个没环:不可能相交: (3) 两链表都有环:slow-fast双指针方法. 程序 public class ListIntersection { // two single list public boolean isIntersectionOfTwoSingleList(ListNode l1, ListNode l2) { if (l1 == null || l2 == nul

&lt;笔试&gt;&lt;面试&gt;C/C++单链表相关(4)判断两链表是否相交,求交点(链表不带环/可能带环)

判断两链表是否相交,求交点(假设链表不带环) 判断两链表是否相交,求交点(假设链表可能带环) RingEntry_Point()等函数见前篇. SListNode* Intersect(SListNode *&L, SListNode *&M)//判断两链表是否相交,求交点(假设链表不带环) {  //思路:若不带环,只有相交/不想交两种情况  // 与RingEntry_Point()函数方法相同:  //     求两个链表长度之差K,再令一个指针从长链表开始先走K步,令另一个指针从短

【IT公司100题-7】-判断两个链表是否相交

问题:有一个单链表,其中可能有一个环,也就是某个节点的next指向的是链表中在它之前的节点,这样在链表的尾部形成一环.1.如何判断一个链表是不是这类链表? 问题扩展:1.如果链表可能有环呢?2.如果需要求出两个链表相交的第一个节点呢? 分析: 在无环的情况下,如果两个链表有结点相同,那么它们下一结点也相同,如此可推出尾结点也相同. 那么只要判断两链表的尾结点是否相同.(O(len1+len2)) 1 struct Node { 2 int data; 3 int Node *next; 4 };

判断两个单链表是否相交及相交的第一个节点

/* 问题: 1.判断两个单链表是否相交 2.找出第一个相交节点 解题思路: 1.若连个链表相交则从相交节点开始以后节点都是一样的 2.通过链表长度判断然后去寻找 */ #include<stdlib.h> #include<stdio.h> /* 创建节点 */ typedef struct STU { char a; struct STU *next; }*SListNode; SListNode ListA; SListNode ListB; /* 创建链表A */ SLis

如何判断两个链表相交及找到第一个相交点

参考原文地址:https://www.cnblogs.com/BeyondAnyTime/archive/2012/07/06/2580026.html 1.问题分析 看看两个链表相交到底是怎么回事吧,有这样的的几个事实:(假设链表中不存在环) (1)一旦两个链表相交,那么两个链表中的节点一定有相同地址. (2)一旦两个链表相交,那么两个链表从相交节点开始到尾节点一定都是相同的节点. 分析出来了问题的本质,那么思路也就自然有了. 2.问题解法 2.1 哈希解法: 既然连个链表一旦相交,相交节点一

判断两个链表是否相交

1 假设两个链表都没有环 解题思路 a. 直接循环判断第一个链表的每个节点是否在第二个链表中.但,这种方法的时间复杂度为O(Length(h1) * Length(h2)).显然,我们得找到一种更为有效的方法,至少不能是O(N^2)的复杂度. b. 针对第一个链表直接构造hash表,然后查询hash表,判断第二个链表的每个节点是否在hash表出现,如果所有的第二个链表的节点都能在hash表中找到,即说明第二个链表与第一个链表有相同的节点.时间复杂度为为线性:O(Length(h1) + Leng

9.判断两个单链表是否相交

9.判断两个单链表是否相交 注意这里是判断是否相交.对于判断问题来讲,相对还是比较简单的.注意单链表并非不能有重复元素. 思路1:O(len1*len2) 把第一个链表的指针值逐项存在hashtable中,遍历第2个链表的每一项的指针值,如果能在第一个链表中找到,则必然相交.但是C++的STL模板中的hash不太会用.所以我使用了set集合,不过貌似set集合是使用遍历的方式来查找元素是否在集合中的,所以效率是比较低的,至少在O(len1*len2)级别. bool judgeIntersect