码迷,mamicode.com
首页 > 其他好文 > 详细

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

时间:2015-01-24 10:16:27      阅读:156      评论:0      收藏:0      [点我收藏+]

标签:

#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;
}

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

标签:

原文地址:http://blog.csdn.net/yuanwei1314/article/details/43082947

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!