链表面试题补充

之前有总结过一些有关链表的面试题,后来在看书和网上又发现了很多比较经典的饿题目,现在再总结一部分。希望对大家有所帮助。

①判断两个链表是否相交,若相交,求交点。(假设链表不带环) 

SListNode* IsIntersect(SListNode* list1,SListNode* list2){
	SListNode* pcur1 = list1;
	SListNode* pcur2 = list2;
	size_t len1 = 1;
	size_t len2 = 1;
	size_t sub;
	while (pcur1->_pNext!=NULL)
	{
		pcur1 = pcur1->_pNext;
		len1++;
	}
	while (pcur2->_pNext!=NULL)
	{
		pcur2 = pcur2->_pNext;
		len2++;
	}
	if(pcur2 == pcur1){
		pcur1 = list1;
		pcur2 = list2;
		printf("list1 和 list2 相交\n");
		if(len1 > len2){
			sub = len1 - len2;
			while (sub--)
			{
				pcur1 = pcur1->_pNext;
			}
		}
		else{
			sub = len2 - len1;
			while (sub--)
			{
				pcur2 = pcur2->_pNext;
			}
		}
		while (pcur1 != pcur2)
		{
			pcur1 = pcur1->_pNext;
			pcur2 = pcur2->_pNext;
		}
		return pcur2;
	}
	return NULL;
}

②判断两个链表是否相交,若相交,求交点。(可能带环)

思路:如果都不带环,那就是第一个问题写的情况,如果带环,那么两个链表一定都带环

一个带环,一个不带环,那么两个链表不可能相交

对于两个都带环的情况,我们处理的方法是:将环内的一点(这个点我们选择其中一个链表的相遇点,也就是pMeet1)的next域置为空,那么此时情况就变成两个单链表的相交的问题。我们可以直接调用解决第一个问题的函数

Tip:函数在设计的时候,在list1和list2插入的值都是正数,为了方便我们测试函数,我们将函数的返回值设置为返回节点的值域,如果没有相交,我们返回-1;

int IsCroseNodeWithCircle(SListNode* list1,SListNode* list2){
	SListNode* pMeet1 = IsCircle(list1);
	SListNode* pMeet2 = IsCircle(list2);
	SListNode* pReturn = NULL;
	if (pMeet1== NULL && pMeet2== NULL)
	{
		pReturn = IsIntersect(list1,list2);
		return pReturn->_pData;
	} 
	else if (pMeet1==NULL || pMeet2 == NULL)
	{
		printf("NotIntersect!\n");
		return -1;
	}
	else{
		pMeet1->_pNext = NULL;
		pReturn = IsIntersect(list1,list2);
		return pReturn->_pData;
	}
}

③求两个已排序单链表中相同的数据

void  IntersectionInList(SListNode* list1,SListNode* list2){
	SListNode* pcur1,*pcur2;
	pcur1 = list1;
	pcur2 = list2;
	while (pcur1 && pcur2)
	{
		if(pcur1->_pData < pcur2->_pData){
			pcur1 = pcur1->_pNext;
		}
		else if(pcur1->_pData > pcur2->_pData){
			pcur2 = pcur2->_pNext;
		}
		else if(pcur1->_pData = pcur2->_pData){
			printf("%d ",pcur2->_pData);
			pcur1 = pcur1->_pNext;
			pcur2 = pcur2->_pNext;
		}
	}
}
④复杂链表的复制

一个链表的每个节点,有一个指向next指针指向 下一个节点,还有一个random指针指向这个链表中的一个随机节点或者NULL,现在要求实现复制这个链表,返回复制后的新链表

在实现复杂链表的实现的时候,我们首先创建一条复杂链表

typedef struct Node{
	int _data;
	struct Node* _pNext;
	struct Node* _rodom;
}Node;
Node* CreatComplexList(){
	Node* Node1 = malloc(sizeof(Node));
	Node* Node2 = malloc(sizeof(Node));
	Node* Node3 = malloc(sizeof(Node));
	Node* Node4 = malloc(sizeof(Node));
	Node1->_data = 1;
	Node1->_pNext = NULL;
	Node1->_rodom = NULL;

	Node1->_pNext = Node2;
	Node2->_data = 2;

	Node2->_pNext = Node3;
	Node3->_data = 3;

	Node3->_pNext = Node4;
	Node4->_data = 4;
	Node4->_pNext = NULL;

	Node1->_rodom = Node3;
	Node2->_rodom = Node1;
	Node3->_rodom = Node3;
	Node4->_rodom = NULL;
	return Node1;
}

这是我们创建的复杂链表


赋值复杂链表的代码实现

Node* CopyComplexList(Node* list){
	Node* pcur = list;
	Node* pNewNode = NULL;
	Node* newlist = NULL;
	while (pcur)
	{
		pNewNode = malloc(sizeof(Node));
		pNewNode->_data = pcur->_data;
		pNewNode->_pNext = pcur->_pNext;
		pcur->_pNext = pNewNode;
		pcur = pNewNode->_pNext;
	}
	pcur = list;
	pNewNode = list->_pNext;
	while (pcur)
	{
		if(pcur->_rodom == NULL)
			pNewNode->_rodom = NULL;
		else{
			pNewNode->_rodom = pcur->_rodom->_pNext;
		}
		pcur = pNewNode->_pNext;
		if(pcur)
			pNewNode = pcur->_pNext;
	}
	pcur = list;
	pNewNode = list->_pNext;
	newlist = list->_pNext;
	while (pcur)
	{
		pcur->_pNext = pNewNode->_pNext;
		pcur = pcur->_pNext;
		if(pcur){
			pNewNode->_pNext = pcur->_pNext;
			pNewNode = pNewNode->_pNext;
		}
	}
	return newlist;
}

关于链表的经典面试题,暂时补充到这里。欢迎各位前来补充。

Tip:限于编者水平,难免有很多不足的地方,欢迎各位大佬前来指正。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值