您的位置:首页 > 其它

判断两个链表是否相交

2014-04-06 17:18 162 查看


判断两个链表是否相交,《编程之美》给出了以下方法:

1.判断第一个链表的每个节点是否在第二个链表中,这种方法的时间复杂度为:O(length(h1)*length(h2)),这种方法很耗时间

2.利用计数的方法 一个简单的做法是对第一个链表的结点地址进行hash排序,建立hash表,然后针对第二个链表的每个节点的地址查询hash表,如果它在哈希表中出现,那么说明第二个链表和第一个链表有共同的结点,这个方法的时间复杂度为O(length(h1)+length(h2)),但是它同时需要附加O(length(h1))的存储空间,以存储哈希表。

3.由于两个链表都没有环,我们可以把第二个链表接在第一个链表后面,如果得到的链表有环,则说明这两个链表相交。否则,这两个链表不相交。

4.先遍历第一个链表,记住最后一个结点,然后遍历第二个链表,到最后一个节点时和第一个链表的最后一个结点做比较,如果相同,则相交;否则,不相交。

本文针对链表有环无环的情况,分别分析了判断是否相交的方法。(1)如果两个链表都没有环,使用《编程之美》给出的解法4,(2)如果两个链表,一个有环,一个没有环,则这两个链表一定不相交(3) 如果两个链表都有环,则分别找到两个链表的环中的一个结点N1和N2(找环中的结点的方法在下面有介绍)。遍历第一个链表的环,看第二个链表的环的某个结点N2是否出现在第一个链表的环中,如果出现,两个有环链表是相交的,否则,两个链表是不相交的。

上面的情况(3)中需要找出有环链表的环中的某个结点,方法和判断链表有环的方法类似。判断链表有环的方法是:定义一个快的指针,每次移动两步,定义一个慢的指针,每个移动一步,如果链表有环,快的指针一定可以追上慢的指针,如果没有环,则两个指针没有相遇的时刻。怎样找出环中的某个结点,利用上面的快指针和慢指针,他们相遇的点必定在环中,相遇的时刻将这个结点返回,即可找到环中的一个结点。

判断链表是否有环,程序为:

int hasloop(node *head)
{
node *fast=head;   //定义两个指针
node *slow=head;
while(fast&&fast->next)   
{
	slow=slow->next;
	fast=fast->next->next;
	if(fast==slow)   //如果有环,两个指针会相遇
		return 1;
}
return 0;
}


判断有环的程序在下面会用到,判断两个链表是否相交的程序为:

int isjoin(node *head1,node *head2)
{
	if(hasloop(head1)+hasloop(head2)==0)  //两个链表都没有环,只需判断最后一个结点是否相同
	{
node *p=head1;
node *p1=head2;
while(p->next)
	p=p->next;
while(p1->next)
	p1=p1->next;
return p1==p;
	}
else if(hasloop(head1)+hasloop(head2)==1)   //两个链表有一个有环,另外一个没有环,这时两个链表不相交
{
	cout<<"not joint"<<endl;
	return 0;
}
else                                       //两个链表都有环的情况
{
	node *fast=head1;
	node *slow=head1;
	node *entry1=0;
	node *entry2=0;
	node *p=head2;
	while(fast&&fast->next)
	{
		slow=slow->next;
		fast=fast->next->next;
		if(fast==slow)
		{
			entry1=fast;            //entry1为第一个链表中的某个结点
			break;
	    }
	}

	fast=head2;
	slow=head2;
	while(fast&&fast->next)
	{
		slow=slow->next;
		fast=fast->next->next;
		if(fast==slow)
		{
			entry2=fast;             //entry2为第二个链表中的某个结点
			break;
	    }
	}
	
	fast=entry1;
	slow=entry1;
	while(fast&&fast->next)          //遍历第一个链表的环,查看entry2是否出现,若出现,则相交
	{
		slow=slow->next;
		fast=fast->next->next;
		if(slow==entry2)
			return 1;
		if(fast==slow)
		{
			break;
	    }
	}
	return 0;
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: