您的位置:首页 > 其它

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

2015-01-24 08:25 344 查看
#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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐