链表的面试题

plist.h

#ifndef __LINKLIST_H__ 
#define __LINKLIST_H__ 

#include <stdio.h>
#include<assert.h>
#include<stdlib.h>


typedef int DataType;
typedef struct Node
{
	DataType data;
	struct Node* next;
}Node, *pNode, List, *pList;
pNode BuyNode(DataType d);
void PushFront(pList* pplist, DataType d);//头部插入
pNode Find(pList plist, DataType d);//查找元素
void PrintLinkList(pList plist);
void PushBack(pList* pplist, DataType d);//尾插
void DestroyLinkList(pList* pplist);//销毁链表

void PrintTailToHead(pList plist);// 从尾到头打印单链表 

void DelNodeNotTail(pNode pos);//删除一个无头单链表的非尾节点 
void InsertNode(pNode pos,DataType d);//在无头单链表的一个节点前插入一个节点 
 
void JosephCycle(pList * pplist, int k);//单链表实现约瑟夫环
 
void ReverseList(pList* pplist);//逆置/反转单链表

void BubbleSort(pList plist);// 单链表排序(冒泡排序) 


pList Merge(pList plist1, pList plist2);//合并两个有序链表,合并后依然有序 

pList  Merge_R(pList plist1, pList plist2);//递归 

pNode FindMidNode(pList plist);// 查找单链表的中间节点,要求只能遍历一次链表 

pNode FindLastKNode(pList plist, int k);// 查找单链表的倒数第k个节点,要求只能遍历一次链表 

pNode CheckCycle(pList plist);// 判断单链表是否带环
int GetCircleLength(pNode meet);//若带环,求环的长度

pNode GetCycleEntryNode(pList plist, pNode meet);//求环的入口点   并计算每个算法的时间复杂度&空间复杂度。
int CheckCross(pList plist1, pList plist2);// 判断两个链表是否相交
pNode GetCrossNode(pList plist1, pList plist2);//若相交,求交点。(假设链表不带环) 

void UnionSet(pList plist1, pList plist2);//求两个有序单链表交集(差集)。

#endif //__LINKLIST_H__ 

plist.c

#include"plist.h"
pNode BuyNode(DataType d)
{
	pNode tmp = (pNode)malloc(sizeof(Node));
	if (tmp == NULL)
	{
		perror("BuyNode::malloc");
		return NULL;
	}
	tmp->data = d;
	tmp->next = NULL;
	return tmp;
}
void PushFront(pList* pplist, DataType d)
{
	assert(pplist != NULL);
	pNode newNode = NULL;
	newNode = BuyNode(d);
	newNode->next = *pplist;
	*pplist = newNode;
}
void PushBack(pList* pplist, DataType d)
{
	pNode newNode = BuyNode(d);
	assert(pplist != NULL);
	if (newNode == NULL)
	{
		exit(EXIT_FAILURE);
	}
	if (*pplist == NULL)
	{
		*pplist = newNode;
	}
	else
	{
		pNode cur = *pplist;
		while ((cur->next) != NULL)
		{
			cur = cur->next;
		}
		cur->next = newNode;
	}
}
pNode Find(pList plist, DataType d)
{
	pNode cur = NULL;
	assert(plist != NULL);
	cur = plist;
	if (plist == NULL)
	{
		return NULL;
	}
	else
	{
		if (cur->data == d)
		{
			return cur;
			cur = cur->next;
		}
	}
	return NULL;
}
void PrintLinkList(pList plist)
{
	pNode cur = plist;
	while (cur)
	{
		printf("&d-->", cur->data);
		cur = cur->next;
	}
	printf("over\n");
}
void DestroyLinkList(pList* pplist)//销毁链表
{
	assert(pplist != NULL);
	pNode cur = *pplist;
	while (cur != NULL)
	{
		pNode del = cur;
		cur = cur->next;
		free(del);
		del = NULL;
	}
	*pplist = NULL;
}
void PrintTailToHead(pList plist)
{
	pNode cur = plist;
	pNode tail = NULL;
	if (plist == NULL)
	{
		return;
	}
	if ((plist->next) == NULL)
	{
		printf("%d", (plist->data));
		return;
	}
	while (plist != tail)
	{
		cur = plist;
		while (cur->next != tail)
		{
			cur = cur->next;
		}
		printf("%d", cur->data);
		tail = cur;
	}
}
void DelNodeNotTail(pNode pos)
{
	pNode del = NULL;
	assert(pos != NULL&&pos->next != NULL);
	del = pos->next;
	pos->data = pos->next->data;
	del->next = pos->next;
	free(del);
	del = NULL;
}
void InsertNode(pNode pos,DataType d)
{
	pNode newNode = NULL;
	assert(pos != NULL);
	DataType tmp = 0;
	newNode = BuyNode(d);
	newNode->next = pos->next;
	pos->next = newNode;
	tmp = pos->data;
	pos->data = newNode->data;
	newNode->data = tmp;
}
void JosephCycle(pList * pplist, int k)//单链表实现约瑟夫环
{
	pNode cur = *pplist;
	while (cur != cur->next)
	{
		int count = k;
		pNode del = NULL;
		while (--count)
		{
			cur = cur->next;
		}
		printf("删除\n", cur->data);
		cur->data = cur->next->data;
		del = cur->next;
		cur->next = del->next;
		free(del);
		del = NULL;
	}
	printf("幸存者\n", cur->data);
}
void ReverseList(pList* pplist)
{
	////第一种
	//assert(pplist != NULL);
	//pNode n1, n2, n3;
	//if (*pplist == NULL)
	//	return;
	//if (*pplist->next == NULL)
	//	return;
	//while (n2)
	//{
	//	n2->next = n1;
	//	n1 = n2;
	//	n2 = n3;
	//	if (n3 != NULL)
	//		n3 = n3->next;
	//}
	//(*pplist)->next = NULL;
	//*pplist = n1;
	//第二种
	assert(pplist != NULL);
	pNode head = NULL;
	pNode cur = NULL;
	pNode tmp = NULL;
	if ((*pplist == NULL) || ((*pplist)->next== NULL))
		return;
	while (cur != NULL)
	{
		cur->next = head;
		head = cur;
		cur = tmp;
		if (tmp != NULL)
			tmp = tmp->next;
	}
	*pplist = head;
}
void BubbleSort(pList plist)
{
	pNode tail = NULL;
	int flag = 0;
	if ((plist == NULL) || (plist->next) == NULL)
	{
		return;
	}
	while (plist != tail)
	{
		pNode cur = NULL;
		pNode next = cur->next;
		while (next != tail)
		{
			if (cur->data > next->data)
			{
				DataType tmp = cur->data;
				cur->data = next->data;
				next->data = tmp;
				flag = 1;
			}
			cur = cur->next;
			next = cur->next;
		}
		tail = cur;
		if (flag == 0)
			return;
	}
}
pList  Merge(pList plist1, pList plist2)
{
	pList newlist = NULL;
	pNode tail = NULL;
	if (plist1 == plist2)
		return NULL;
	if (plist1 == NULL)
		return plist2;
	if (plist2 == NULL)
		return plist1;
	if (plist1->data < plist2->data)
	{
		newlist = plist1;
		plist1 = plist1->next;
	}
	else
	{
		newlist = plist2;
		plist2 = plist2->next;
	}
	tail = newlist;
	while ((plist1 != NULL) && (plist2 != NULL))
	{
		if (plist1->data < plist2->data)
		{
			tail->next = plist1;
			plist1 = plist1->next;
		}
		else
		{
			tail->next = plist2;
			plist2 = plist2->next;
		}
		tail = tail->next;
	}
	if (plist1 == NULL)
	{
		tail->next = plist2;
	}
	else if (plist2 == NULL)
	{
		tail->next = plist1;
	}
	return newlist;
}
pList  Merge_R(pList plist1, pList plist2)
{
	pList newlist = NULL;
	pNode tail = NULL;
	if (plist1 == plist2)
		return NULL;
	if (plist1 == NULL)
		return plist2;
	if (plist2 == NULL)
		return plist1;
	if ((plist1->data )< (plist2->data))
	{
		newlist = plist1;
		newlist->next = Merge_R(plist1->next, plist2);
	}
	else
	{
		newlist = plist2;
		newlist->next = Merge_R(plist1, plist2->next);
	}
	return newlist;
}
pNode FindMidNode(pList plist)
{
	pNode fast = plist;
	pNode slow = plist;
	if ((plist == NULL) || (plist->next) == NULL)
		return plist;
	while ((fast != NULL) && (fast->next) != NULL)
	{
		fast = fast->next->next;
		slow = slow->next;
	}
	return slow;
}
pNode FindLastKNode(pList plist, int k)
{
	pNode fast = NULL;
	pNode slow = NULL;
	if (k == 0)
		return;
	if (plist == NULL)
		return plist;
	while (k--)
	{
		if (fast == NULL)
		{
			return NULL;
		}
		fast = fast->next;
	}
	while (fast != NULL)
	{
		fast = fast->next;
		slow = slow->next;
	}
	return slow;
}
pNode CheckCycle(pList plist)
{
	pNode fast = NULL;
	pNode slow = NULL;
	if (plist == NULL)
		return plist;
	while ((fast != NULL) && (fast->next) != NULL)
	{
		fast = fast->next->next;
		slow = slow->next;
		if (fast == slow)
			return slow;
	}
	return NULL;
	
}
int GetCircleLength(pNode meet)
{
	pNode cur = NULL;
	assert(meet != NULL);
	cur = meet->next;
	int len = 1;
	while (cur != meet)
	{
		len++;
		cur = cur->next;
	}
	return len;
}
pNode GetCycleEntryNode(pList plist, pNode meet)
{
	pNode cur = plist;
	if (plist == NULL);
	return NULL;
	assert(meet != NULL);
	while (cur != meet)
	{
		cur = cur->next;
		meet = meet->next;
	}
	return meet;
}
int CheckCross(pList plist1, pList plist2)
{
	pNode end1 = plist1;
	pNode end2 = plist2;
	if ((plist1 == NULL) && (plist2 == NULL))
		return NULL;
	while (end1->next != NULL)
	{
		end1 = end1->next;
	}
	while (end2->next != NULL)
	{
		end2 = end2->next;
	}
	return end1 = end2;
}
pNode GetCrossNode(pList plist1, pList plist2)
{
	int len1 = 0;
	int len2 = 0;
	pNode cur1 = plist1;
	pNode cur2 = plist2;
	int gap = 0;
	while (cur1)
	{
		len1++;
		cur1 = cur1->next;
	}
	while (cur2)
	{
		cur2 = cur2->next;
	}
	gap = abs(len1 - len2);
	cur1 = plist1;//长
	cur2 = plist2;//短
	if (len1 < len2)
	{
		cur1 = plist2;
		cur2 = plist1;
	}
	while (cur1 != cur2)
	{
		cur1 = cur1->next;
		cur2 = cur2->next;
	}
	return cur2;
}
void UnionSet(pList plist1, pList plist2)
{
	if ((plist1 == NULL) || (plist2) == NULL)
		return;
	while (plist1&&plist2)
	{
		if (plist1->data > plist2->data)
		{
			plist1 = plist1->next;
		}
		else if (plist1->data > plist2->data)
		{
			plist2 = plist2->next;
		}
		else
		{
			printf("%d", plist1->data);
			plist1 = plist1->next;
			plist2 = plist2->next;
		}
	}
}

test.c

#include"plist.h"
void TestPrintTailToHead()
{
	Node * plist = NULL;
	PushFront(&plist, 1);
	PushFront(&plist, 2);
	PushFront(&plist, 3);
	PushFront(&plist, 4);
	PrintLinkList(plist);
	PrintTailToHead(plist);
}
void TestDelNodeNotTail()
{
	Node * pos = NULL;
	Node * plist = NULL;
	PushFront(&plist, 1);
	PushFront(&plist, 2);
	PushFront(&plist, 3);
	PushFront(&plist, 4);
	PrintLinkList(plist);
	pos = Find(plist, 3);
	DelNodeNotTail(plist);
	if (pos != NULL)
	{
		DelNodeNotTail(pos);
	}
	PrintLinkList(plist);
}
void TestInsertNode()
{
	Node * pos = NULL;
	Node * plist = NULL;
	PushFront(&plist, 1);
	PushFront(&plist, 2);
	PushFront(&plist, 3);
	PushFront(&plist, 4);
	PrintLinkList(plist);
	pos = Find(plist, 3);
	DelNodeNotTail(plist);
	if (pos != NULL)
	{
		InsertNode(pos,5);
	}
	PrintLinkList(plist);
}
void TestJosephCycle()
{
	int i = 0;
	pNode plist = NULL;
	for (i = 1; i <= 10; i++)
	{
		PushBack(&plist, i);
	}
	PrintLinkList(plist);
	//构成环
	Find(plist, 10)->next = plist;
	JosephCycle(&plist,3);
}
void TestReverseList()
{
	int i = 0;
	pNode plist = NULL;
	for (i = 1; i <= 10; i++)
	{
		PushBack(&plist, i);
	}
	PrintLinkList(plist);
	ReverseList(&plist);
	PrintLinkList(plist);
}
void TestBubbleSort()
{
	int i = 0;
	pNode plist = NULL;
	for (i = 1; i <= 10; i++)
	{
		PushBack(&plist, 6-i);
	}
	BubbleSort(plist);
	PrintLinkList(plist);
}
void TestMerge()
{
	pList  plist1 = NULL;
	pList  plist2 = NULL;
	pList  plist = NULL;
	int i = 0;
	for(i = 1; i<=9; i+=2)
	{
		PushBack(&plist1, i);
	}
	PrintLinkList(plist1);
	for(i = 2; i<=6; i+= 2)
	{
		PushBack(&plist2, i);
	}
	PrintLinkList(plist2);
	plist = Merge(plist1, plist2);
	PrintLinkList(plist);
	DestroyLinkList(&plist);
}
void TestFindMidNode()
{
	pList plist = NULL;
	int i = 0;
	pNode pos = NULL;
	for (i = 1; i <= 9; i += 2)
	{
		PushBack(&plist, i);
	}
	PrintLinkList(plist);
	pos = FindMidNode(plist);
	if (pos != NULL)
	{
		printf("%d\n", pos->data);
	}
}
void TestFindLastKNode()
{
	pList plist = NULL;
	int i = 0;
	pNode pos = NULL;
	for (i = 0; i < 10; i++)
	{
		PushBack(&plist, i);
	}
	pos = FindLastKNode(plist, 3);
	if (pos != NULL)
		printf("%d\n", pos->data);
}
void TestCheckCycle()
{
	pList plist = NULL;
	int i = 0;
	pNode pos = NULL;
	for (i = 1; i <= 5; i++)
	{
		PushBack(&plist, i);
	}
	Find(plist, 5)->next = Find(plist, 3);
	pos = CheckCycle(plist);
	if (pos != NULL)
	{
		printf("带环,相遇点是%d\n", pos->data);
		printf("环的长度:\n",GetCircleLength(pos));
	}
	else
	{
		printf("不带环\n");
	}
}
void TestGetCycleEntryNode()
{
	pList plist = NULL;
	int i = 0;
	pNode pos = NULL;
	for (i = 1; i <= 5; i++)
	{
		PushBack(&plist, i);
	}
	Find(plist, 5)->next = Find(plist, 3);
	pos = CheckCycle(plist);
	if (pos != NULL)
	{
		printf("带环,相遇点是%d\n", pos->data);
		printf("环的长度:%d\n",GetCircleLength(pos));
		printf("%d\n", GetCycleEntryNode(plist,pos)->data);
	}
	else
	{
		printf("不带环\n");
	}
}
void TestCheckCross()
{
	pList  plist1 = NULL;
	pList  plist2 = NULL;
	pList plist = NULL;
	int i = 0;
	pNode pos = NULL;
	for (i = 1; i <= 9; i += 2)
	{
		PushBack(&plist1, i);
	}
	PrintLinkList(plist1);
	for (i = 2; i <= 6; i += 2)
	{
		PushBack(&plist2, i);
	}
	PrintLinkList(plist2);
	Find(plist2, 6)->next = Find(plist1, 3);
	if (CheckCross(plist1, plist2)==1)
	{
		printf("相交\n");
		pos=GetCrossNode(plist1, plist2);
		printf("交点是%d\n", pos->data);

	}
	else
	{
		printf("不相交\n");
	}
		
}

void TestUnionSet()
{
	pList  plist1 = NULL;
	pList  plist2 = NULL;
	pList  plist = NULL;
	int i = 0;
	for (i = 1; i <= 9; i++)
	{
		PushBack(&plist1, i);
	}
	PrintLinkList(plist1);
	for (i = 2; i <= 6; i++)
	{
		PushBack(&plist2, i);
	}
	PrintLinkList(plist2);
	UnionSet(plist1, plist2);
}
int main()
{
	/*TestPrintTailToHead();
	TestDelNodeNotTail();
	TestInsertNode();
	TestJosephCycle();
	TestReverseList();
	TestBubbleSort();
	TestMerge();
	TestFindMidNode();
	TestFindLastKNode();
	TestCheckCycle();
	TestGetCycleEntryNode();
	TestCheckCross();
	TestUnionSet();*/
	return 0;
}

 

    原文作者:ReginaPhilange
    原文地址: https://blog.csdn.net/qq_41268108/article/details/81710221
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞