第7题 微软亚院之编程判断俩个链表是否相交 给出俩个单向链表的头指针,比如h1,h2,判断这俩个链表是否相交,并找出第一个相交结点。

思路

1.判断两链表是否相交

可以用两个指针,p1End, p2End,分别指向链表h1, h2的最后一个结点。如果p1End = p2End说明两链表相交。

2.找出相交的第一个结点

可以先求得链表h1, h2的长度之差的绝对值sub, 将较长的那个链表向后移动sub个位置后。从两链表的当前位置开始一直往后比较,第一个相等的结点即是第一个相交结点。

#include <iostream>
using namespace std;

typedef struct tagNode
{
	tagNode *pNext;
	int len;
	int data;
}Node;

//判断n1, n2是否相交,相交返回true,否则返回false
bool isIntersect(Node *n1, Node *n2)
{
	Node *p1End = NULL;
	Node *p2End = NULL;

	//将p1End指向n1的最后一个节点
	while (NULL != n1)
	{
		p1End = n1;
		n1 = n1->pNext;
	}

	//将p2End指向n2的最后一个节点
	while (NULL != n2)
	{
		p2End = n2;
		n2 = n2->pNext;
	}

	//相等说明n1, n2相交
	if (p1End == p2End)
	{
		return true;
	}
	else
	{
		return false;
	}
}

//返回n1, n2相交的第一个节点
Node *FirstIntersect(Node *n1, Node *n2)
{
	int n1Len = n1->len;
	int n2Len = n2->len;
	int sub = 0;

	//把长度较长的链表往后移动sub个位置,使n1,n2相对链表尾的节点个数相同
	if (n1Len > n2Len)
	{
		sub = n1Len - n2Len;
		while (sub--)
		{
			n1 = n1->pNext;
		}
	}
	else
	{
		sub = n2Len - n1Len;
		while (sub--)
		{
			n2 = n2->pNext;
		}
	}

	//n1,n2第一次相等的那个结点,就是第一个相交的结点
	while (n1 != n2)
	{
		n1 = n1->pNext;
		n2 = n2->pNext;
	}

	return n1;
}

//为了方便实验,此函数的功能是让两个链表相交
void MakeIntersect(Node *n1, Node *n2)
{
	int i = 2;
	int j = 3;

	while (i--)
	{
		n1 = n1->pNext;
	}

	while (j--)
	{
		n2 = n2->pNext;
	}

	n1->pNext = n2;

}

//创建链表,并返回头指针
Node *CreateList()
{
	Node *head = NULL;
	Node *tail = NULL;
	Node *temp = NULL;
	static int k = 1;	

	tail = head = new Node;
	head->data = k;
	head->len = 1;
	head->pNext = NULL;

	for (int i = 0; i < 6; ++i)
	{
		++k;
		temp = new Node;
		temp->data = k;
		++(temp->len);
		temp->pNext = NULL;
		
		tail->pNext = temp;
		tail = temp;
	
	}

	return head;
}

//遍历链表
void Tranverse(Node *head)
{
	Node *pCur = head;
	while (NULL != pCur)
	{
		cout<<pCur->data<<endl;
		pCur = pCur->pNext;
	}
}


int main()
{
	Node *pFirstList = CreateList();
	Node *pSecondList = CreateList();
	Node *IntersectNode = NULL;
	cout<<"分别遍历2个链表"<<endl;
	Tranverse(pFirstList);
	cout<<"\n链表2"<<endl;
	Tranverse(pSecondList);

	cout<<"\n两链表相交后"<<endl;
	MakeIntersect(pFirstList, pSecondList);
	Tranverse(pFirstList);
	cout<<"\n链表2"<<endl;
	Tranverse(pSecondList);	

	//返回相交的第一个结点并输出
	if (isIntersect(pFirstList, pSecondList))
	{
		cout<<"相交结点为"<<endl;
		IntersectNode = FirstIntersect(pFirstList, pSecondList);
		cout<<IntersectNode->data<<endl;
	}
	else
	{
		cout<<"不相交"<<endl;
	}


	return 1;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值