两个单链表的交叉结点

来源:互联网 发布:注册短信验证php 编辑:程序博客网 时间:2024/06/04 00:22

问题1:判断两个单链表是否有交叉。

算法:两个单链表只能存在Y型交叉,不会存在X型交叉。最简单的方式是直接遍历到两个链表的最后一个节点,判断它们是否相同。

代码:

bool isIntersected(node_t *a,node_t *b){node_t *p,*q;if(!a || !b) return false;for(p=a;p->next;p=p->next);for(q=b;q->next;q=q->next);return (p==q);}

问题2:找两个链表相交的交点。

算法:假设两个链表a,b.a比b长k个结点(k>=0). 那么当a_ptr,b_ptr两个指针同时分别遍历a,b的时候, 必然b_ptr先到达结尾(NULL),而此时a_ptr落后a的尾巴k个结点.如果此时再从a的头发出一个指针t,继续和a_ptr 一起走,当a_ptr达到结尾(NULL)时,t恰好走了k个结点.此时从b的头发一个指针s, s和t一起走,因为a比b长k个结点,所以,t和s会一起到达交点.

代码:

node_t * intersect_list(node_t *a,node_t*b){node_t *p,*q;for(p=a,q=b;p && q;p=p->next,q=q->next);node_t *k = (p==NULL)?q:p;node_t *t = (p==NULL)?b:a;node_t *s = (p==NULL)?a:b;for(;k;k=k->next,t=t->next);for(;s!=t;s=s->next,t=t->next);return t;}
测试程序:

#include <iostream>using namespace std;typedef struct node_t{char* data;node_t * next;};void DisplayList(node_t *ptr){for(;ptr;ptr = ptr->next)printf("%s ",ptr->data);printf("\n");}node_t * intersect_list(node_t *a,node_t*b){node_t *p,*q;for(p=a,q=b;p && q;p=p->next,q=q->next);node_t *k = (p==NULL)?q:p;node_t *t = (p==NULL)?b:a;node_t *s = (p==NULL)?a:b;for(;k;k=k->next,t=t->next);for(;s!=t;s=s->next,t=t->next);return t;}bool isIntersected(node_t *a,node_t *b){node_t *p,*q;if(!a || !b) return false;for(p=a;p->next;p=p->next);for(q=b;q->next;q=q->next);return (p==q);}void main(){node_t e = {"e",NULL},d = {"d",&e}, c = {"c",&d}, b = {"b",&c}, a = {"a",&b};node_t y = {"y",&d}, x = {"x",&y};node_t m = {"m",NULL};DisplayList(&a);DisplayList(&x);DisplayList(&m);node_t *t = intersect_list(&a,&x);printf("List a and List x intersected: %d\n",isIntersected(&a,&x));printf("List a and List m intersected: %d\n",isIntersected(&a,&m));DisplayList(t);}
测试输出:

a b c d e x y d e m List a and List x intersected: 1List a and List m intersected: 0d e 


REF:

1,http://www.zhihu.com/question/20218641

2,http://hit9.org/oldblog/blog/C/posts/25.html#9




0 0
原创粉丝点击