单链表是否相交

题目:有两个带头结点的单链表L1,L2,判断它们是否相交(它们中是否有相同的结点)

解题思路:

L1,L2中任何一个链表为空它们不相交

因为单链表中可能有环,所以分3种情况讨论

1、L1,L2中都没有环,那么可以通过判断它们中最后一个结点是否相同,来判断它们是否相交

2、L1,L2中一个有环,一个没有环,那么它们一定不相交

3、L1,L2中都有环,那么只有当它们的环相同时,它们才相交,当它们在进入环之前有相同的结点时,它们交点的个数大于环中结点的个数,当它们进入环时才有第一个相同的结点时,它们交点的个数等于于环中结点的个数,这两种情况下,都可以通过判断它们环的入口结点是否相同来判断它们是否相交。

ADT定义如下

#define ElemType char

typedef struct LNode{

ElemType data;

LNode *next;

}LNode,*LinkList;

算法实现:

bool isIntersect(LinkList &L1,LinkList &L2)

{

if(L1==NULL||L2==NULL) return false;//L1,L2中任何一个链表为空它们不相交

//L1,L2中都没有环

if(!(hasCircle(L1)||hasCircle(L2)))

{

LNode* p=L1;

LNode* q=L2;

while(p->next)

{

p=p->next;

}

while(q->next)

{

q=q->next;

}

if(p==q) return true;//两个无环单链表,最后一个结点相同时,它们相交

return false;

}

//L1,L2中都有环

else if(hasCircle(L1)&&hasCircle(L2))

{

if(searchEntranceNode(L1)== searchEntranceNode(L2)) return true;//两个有环单链表,它们环的入口结点相同时,它们相交

return false;

}

//L1,L2中一个有环,一个没有环

else

{

return false;//两个单链表,一个有环,一个无环,它们一定不相交

}

}

hasCircle()方法是用来判断单链表是否有环,searchEntranceNode()方法是用来找单链表中环的入口结点的

我的一篇博文有写出它们的具体实现:单链表是否相交

拓展:有两个带头结点的单链表L1,L2,判断它们是否相交,并求出首次相交的结点

解题思路:

当L1与L2相交时,若L1与L2中都没有环,那么求出两个单链表中结点个数之差的绝对值dCount,让结点个数多的单链表从头结点开始往下走dCount步,让结点个数少的单链表从头结点开始往后走,然后同时让两个单链表每次往后走一步,直到他们相等,那么这个结点就是首次相交的结点。若L1与L2中都有环,求出单链表L1与L2从头结点到环入口结点的结点总个数count,求出两者之差的绝对值,让count大的单链表从头结点开始往下走dCount步,让count大的的单链表从头结点开始往后走,然后同时让两个单链表每次往后走一步,直到他们相等,那么这个结点就是首次相交的结点。

算法实现:

LNode* searchFirstIntersectNode(LinkList &L1,LinkList &L2)

{

if(isIntersect(L1,L2)) return NULL;//单链表L1与L2不相交时,返回NULL

if(!hasCircle(L1)) //L1中没有环时,L1与L2中都没有环

{

int count1=1;//单链表L1中结点的个数,包括头结点

int count2=1;//单链表L2中结点的个数,包括头结点

LNode* p=L1;

LNode* q=L2;

while(p->next)

{

p=p->next;

count1++;

}

while(q->next)

{

q=q->next;

count2++;

}

if(count1>=count2)//单链表L1比单链表L2长或两者一样长时

{

int dCount=count1-count2;//单链表L1比单链表L2多出的结点的个数

p=L1;

q=L2;

while(dCount>0)

{

p=p->next;

}

while(p)

{

if(p==q) return p;

p=p->next;

q=q->next;

}

}

else

{

int dCount=count2-count1;//单链表L2比单链表L1多出的结点的个数

p=L1;

q=L2;

while(dCount>0)

{

q=q->next;

}

while(q)

{

if(p==q) return p;

p=p->next;

q=q->next;

}

}

}

else //L1有环时,此时L1与L2都有环

{

int count1=1;//单链表L1中从头结点到环的入口结点之间所有结点的个数,包括头结点与环的入口结点

int count2=1;//单链表L2中从头结点到环的入口结点之间所有结点的个数,包括头结点与环的入口结点

LNode* p=L1;

LNode* q=L2;

while(p!= searchEntranceNode(L1))

{

p=p->next;

count1++;

}

while(q!=searchEntranceNode(L2))

{

q=q->next;

count2++;

}

if(count1>=count2)//单链表L1比单链表L2从头结点到环的入口结点之间所有结点的个数长或两者一样长时

{

int dCount=count1-count2;//单链表L1比单链表L2从头结点到环的入口结点之间所有结点的个数多出的结点的个数

p=L1;

q=L2;

while(dCount>0)

{

p=p->next;

}

while(p)

{

if(p==q) return p;

p=p->next;

q=q->next;

}

}

else

{

int dCount=count2-count1;//单链表L2比单链表L1从头结点到环的入口结点之间所有结点的个数多出的结点的个数

p=L1;

q=L2;

while(dCount>0)

{

q=q->next;

}

while(q)

{

if(p==q) return p;

p=p->next;

q=q->next;

}

}

}

return NULL;

}

上面的程序分两种情况:L1与L2中都没有环时,求首次相交结点;L1与L2中都有环时,求首次相交结点。其实L1与L2中都有环时,求首次相交结点,可以类似的看成L1与L2中都没有环时,求首次相交结点。只需要令L1与L2环中入口结点的next为空,那么L1与L2就成了没有环的单链表了。

PS:此时searchFirstIntersectNode()方法中的参数不是引用类型,因为L1与L2中都有环,会将L1与L2都转变成没有环的单链表,这个过程会改变L1与L2,但是我们不希望这个改变对原始的L1和L2进行改变,所以参数没有用引用类型

LNode* searchFirstIntersectNode(LinkList L1,LinkList L2)

{

if(isIntersect(L1,L2)) return NULL;//单链表L1与L2不相交时,返回NULL

if(hasCircle(L1)) searchEntranceNode(L1)->next=NULL;//令L1中环入口结点的next为NULL

int count1=1;//单链表L1中结点的个数,包括头结点

int count2=1;//单链表L2中结点的个数,包括头结点

LNode* p=L1;

LNode* q=L2;

while(p->next)

{

p=p->next;

count1++;

}

while(q->next)

{

q=q->next;

count2++;

}

if(count1>=count2)//单链表L1比单链表L2长或两者一样长时

{

int dCount=count1-count2;//单链表L1比单链表L2多出的结点的个数

p=L1;

q=L2;

while(dCount>0)

{

p=p->next;

}

while(p)

{

if(p==q) return p;

p=p->next;

q=q->next;

}

}

else

{

int dCount=count2-count1;//单链表L2比单链表L1多出的结点的个数

p=L1;

q=L2;

while(dCount>0)

{

q=q->next;

}

while(q)

{

if(p==q) return p;

p=p->next;

q=q->next;

}

}

return NULL;

}

时间: 2024-11-17 04:19:44

单链表是否相交的相关文章

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

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

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

/* 问题: 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

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

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

判断两个单链表是否相交

题目描述: 给定两个单链表的头节点head1和head2,如何判断两个链表是否相交?相交的话返回true,不想交的话返回false. 给定两个链表的头结点head1和head2.请返回一个bool值代表它们是否相交. 链表中节点的类型设置如下: class ListNode { int val; ListNode next = null; ListNode(int val) { this.val = val; } } 思路: 1.首先判断是否有环, 若两个链表都没有环,则进行无环单链表判断是否相

每日一题3:判断单链表是否相交

由于单链表的特殊性,如果某一链表与另一链表相交,那么从相交的节点开始,以后两个链表的每个节点都相同,因此判断两个链表是否相交,只需判断每条链表的最后一个节点是否相同即可! #include "stdafx.h" #include <iostream> using namespace std; struct list_node { int data; list_node* next; }; list_node* CreateList(int datas[],int n) {

判断2个单链表是否相交,并求出第一个相交结点

不考虑单链表有环的情况下 如果2个单链表相交,一定是Y型链表 1.遍历2个链表到尾结点,记录2个链表的长度x,y 2.尾结点相同,则相交. 3.从表头开始,长链表先走|x-y|步,之后2个链表一起走,判断第一个相同的点. 1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <string.h> 4 typedef struct student //定义链表结构 5 { 6 int num; 7 struct stu

1.11判断两个无环单链表是否相交

判断两个无环单链表是否交叉 题目描述: 如上图,这两个链表相交于结点5,要求判断两个链表是否相交,如果相交,找出相交处的结点. 解题思路: 方法一:Hash 法 如上图所示,如果两个链表相交,那么它们一定会有公共的结点,由于结点的地址或引用可以作为结点的唯一标识,因此,可以通过判断两个链表中的结点是否有相同的地址或引用来判断链表是否相交. 方法二:首尾相接法 将这两个链表首尾相连(例如把链表headl尾结点链接到head2的头指针),然后检测这个链表是否存在环,如果存在,则两个链表相交,而环入口

java判断两个单链表是否相交

转载于:http://blog.csdn.net/happymatilian/article/details/47811161 思路: 链表分有环链表和无环链表,如果两个链表存在相交,则只有两种可能,两个链表都无环或者都有环. (1)如果链表都无环,则先判断链表的尾指针是否一样,如果不一样,则没有相交.如果一样,则找出两个链表的长度差,将两个链表从距离尾节点同样的距离进行扫描,如果相交,则必然有一处扫描节点相同.实例数据List1:1->2->3->4->5->6->7

C实现之单链表是否相交

1 # include<stdio.h> 2 struct Slist{ 3 int size; 4 struct sl* head; 5 }; 6 struct sl{ 7 int k; 8 struct sl* next; 9 }; 10 typedef struct Slist Sl; 11 typedef struct sl sl; 12 void init(Sl* m,int k){ 13 sl* p = (sl *)malloc(sizeof(sl)); 14 p->k =