单链表相关的面试题

SList.h

void PrintListFromTail2Head(PNode pHead);//从尾到头打印单链表
void EraseNotTailNode(PNode pos);//删除非尾结点
void InsertFront(PNode pos,DataType data);//无头单链表插入结点
void JosephCircle(PNode *ppHead,size_t M);//约瑟夫环

void ReverseList(PNode *ppHead);//链表逆置
PNode ReverseList_P(PNode pHead);//链表逆置(头插法)
void BubbleSort(PNode pHead);//冒泡排序
PNode FindMidlleNode(PNode pHead);//查找单链表的中间结点,要求只能遍历一次
PNode FindLastKNode(PNode pHead, size_t K);//	查找单链表的倒数第K个结点   
int DeleteLastKNode(PNode* ppHead,size_t K);//删除倒数第k个结点
PNode MergeLiist(PNode pHead1,PNode pHead2);//合并两个有序的单链表
PNode HasCircle(PNode pHead);//判断单链表是否带环
size_t GetCircleLen(PNode pHead);//求环的长度

SList.c

void PrintListFromTail2Head(PNode pHead)//打印结点
//采用函数递归  1-->2-->3--4-->NULL  递归了5次  
										//时间复杂度:O(N+1)     //空间复杂度:O(N+1)
{
	if (pHead)
	{
		PrintListFromTail2Head(pHead->_pNext);
		printf("%d   ",pHead->_data);
	}

	//循环实现
	//...
}


void EraseNotTailNode(PNode pos)//替换法删除(腾讯面试题)
{
	PNode pDel;
	if (NULL == pos || NULL == pos->_pNext)
		return;
	pDel = pos->_pNext;//pDel初始化为pos结点的下一个结点位置
	pos->_data = pDel->_data;//将要删除的结点数据赋给pos结点。
	pos->_pNext = pDel->_pNext;//使得pos的下一个结点指向删除结点的下一个结点

	free(pDel);//删除结点
}

  
void InsertFront(PNode pos, DataType data)//无头单链表插入结点
{
	PNode pNewNode = NULL;
	if (NULL == pos)
		free(pNewNode);
		return;
	pNewNode = BuySListNode(pos->_data);
	pNewNode->_pNext = pos->_pNext;
	pos->_pNext = pNewNode;
	pos->_data = data;
}

void JosephCircle(PNode *ppHead, size_t M)//约瑟夫环
{
	PNode pCur = NULL;
	assert(ppHead);

	pCur = *ppHead;
	while (pCur != pCur->_pNext)
	{
		//1.报数:
		size_t count = M;
		PNode pDel = NULL;
		while (--count)
			pCur = pCur->_pNext;

		//2.删除:(替换法)---(非尾结点)
		pDel = pCur->_pNext;
		pCur->_data = pDel->_data;
		pCur->_pNext = pDel->_pNext;
		free(pDel);
	}
	*ppHead = pCur;
}


void ReverseList(PNode *ppHead)//链表逆置 (以下两种方法均不能处理带环问题,如果要处理,可先将环拆开,然后按照正常方法进行逆置,最后将头尾结点指向头结点即可)
{
	PNode pPre = NULL;
	PNode pCur = NULL;
	PNode pNext = NULL;

	if (NULL == ppHead || NULL == (*ppHead)->_pNext)
		return;
	pCur = *ppHead;
	while (pCur)
	{
		pNext = pCur->_pNext;

		pCur->_pNext = pPre;
		pPre = pCur;
		pCur = pNext;
	}
	*ppHead = pPre; //已经变成头结点,更新头结点

}



PNode ReverseList_P(PNode pHead)//链表逆置(带环:将pHead指向pNewHead) 
{
	PNode pCur = pHead;
	PNode  pNext = NULL;
	PNode pNewHead = NULL;
	while (pCur)
	{
		pNext = pCur->_pNext;
		pCur->_pNext = pNewHead;//先链接
		pNewHead = pCur;

		pCur = pNext;
	}

	return pNewHead;
}


void BubbleSort(PNode pHead)//冒泡排序
{
	PNode pCur = NULL;
	PNode pNext = NULL;
	PNode pTail = NULL;
	int IsChange = 0;//设置一个标记

	if (NULL == pHead || NULL == pHead->_pNext)
		return;
	while (pHead != pTail)
	{
		pCur = pHead;
		pNext = pCur->_pNext;
		IsChange = 0;//恢复标记

		while (pNext != pTail)
		{
			if (pCur->_data  >  pNext->_data)
			{
				DataType temp = pCur->_data;
				pCur->_data = pNext->_data;
				pNext->_data = temp;
				IsChange = 1;//还没有排好
			}
			pCur = pNext;
			pNext = pCur->_pNext;
		}

		if (!IsChange)
			return;

		pTail = pCur;
	}

}


PNode FindMidlleNode(PNode pHead)//寻找中间结点
{
	PNode pSlow = pHead;
	PNode pFast = pHead;

	while (pFast &&  pFast->_pNext)//保证第一步和第二步都走成功
	{
		pSlow = pSlow->_pNext;
		pFast = pFast->_pNext->_pNext;
	}
	return pSlow;
}



PNode FindLastKNode(PNode pHead,size_t K)//寻找倒数第K个结点    //时间复杂度:O(N)
{
	PNode pFast = pHead;
	PNode pSlow = pHead;
	if (NULL == pHead || 0 == K)
		return NULL;
	//. 定义两个指针pFast和pSlow  让pFast先走k步(k--)---> pFast == NULL
                                  //k-1步(--k)  ----> pFast->next == NULL
	while (--K)
	{
		if (NULL == pFast)
			return NULL;
		pFast = pFast->_pNext;
	}
	//然后同时走
	while (pFast->_pNext)
	{
		pSlow = pSlow->_pNext;
		pFast = pFast->_pNext;
	}
	return pSlow;
}


int DeleteLastKNode(PNode* ppHead, size_t K)//删除倒数第K个结点
{
	PNode pFast = NULL;
	PNode pSlow = NULL;
	PNode pPreSlow = NULL;
	assert(ppHead);

	if (NULL == *ppHead || 0 == K)
		return 0;
	pFast = pSlow = *ppHead;
	while (K--)
	{
		if (NULL == pFast)
			return 0;
		pFast = pFast->_pNext;
	}
	while (pFast)
	{
		pPreSlow = pSlow;
		pSlow = pSlow->_pNext;
		pFast = pFast->_pNext;
	}
	if (pSlow == *ppHead)
		*ppHead = pSlow->_pNext;
	else
		pPreSlow->_pNext = pSlow->_pNext;
	free(pSlow);
	return 1;
}

PNode MergeLiist(PNode pHead1, PNode pHead2)//合并两个有序单链表
{
	PNode pL1 = pHead1;
	PNode pL2 = pHead2;
	PNode pNewNode = NULL;
	PNode pTail = NULL;

	if (NULL == pHead1 || NULL == pHead2)
		return (pHead1) ? pHead1 : pHead2; 

	if (pL1->_data < pL2->_data)
	{
		pNewNode = pL1;
		pTail = pL1;//标记
		pL1 = pL1->_pNext;
	}
	else
	{
		pNewNode = pL2;
		pTail = pL2;
		pL2 = pL2->_pNext;
	}


	while (pL1 && pL2)
	{
		if (pL1->_data < pL2->_data)
		{
			pTail->_pNext = pL1;
			pL1 = pL1->_pNext;
		}
		else
		{
			pTail->_pNext = pL2;
			pL2 = pL2->_pNext;
		}
		pTail = pTail->_pNext;
	}
	if (pL1)
		pTail->_pNext = pL1;
	if (pL2)
		pTail->_pNext = pL2;

	return pNewNode;
}

PNode HasCircle(PNode pHead)//判断单链表是否带环
{
	PNode pFast = pHead;
	PNode pSlow = pHead;
	
	while (pFast && pFast->_pNext)
	{
		pFast = pFast->_pNext->_pNext;
		pSlow = pSlow->_pNext;

		if (pFast == pSlow)
			return 1;
	}
	return 0;
}

size_t GetCircleLen(PNode pHead)//求环的长度(R)
{
	PNode  pMeetNode = HasCircle(pHead);
	PNode pCur;
	size_t len = 1;

	if (NULL == pMeetNode)
		return 0;
	pCur = pMeetNode;
	while (pCur->_pNext != pMeetNode)
	{
		len++;
		pCur = pCur->_pNext;
	}
	return len;
}

Test.c

void TestSList5()
{
	PNode  pHead;//给出结点
	SListInit(&pHead);//初始化

	SListPushBack(&pHead, 1);
	SListPushBack(&pHead, 2);
	SListPushBack(&pHead, 3);
	SListPushBack(&pHead, 4);
	SListPrint(pHead);
	PrintListFromTail2Head(pHead);
}

void TestSList6()//测试约瑟夫环
{
	PNode  pHead,pTailNode;//给出结点
	SListInit(&pHead);//初始化
	SListPushBack(&pHead, 1);
	SListPushBack(&pHead, 2);
	SListPushBack(&pHead, 3);
	SListPushBack(&pHead, 4);
	SListPushBack(&pHead, 5);
	SListPushBack(&pHead, 6);
	SListPushBack(&pHead, 7);
	SListPrint(pHead);

	pTailNode = Find(pHead,7);
	pTailNode->_pNext = pHead;

	JosephCircle(&pHead,3);
	pHead->_pNext = NULL;
	
}

void TestSList7()//链表逆置
{
	PNode  pHead;//给出结点
	SListInit(&pHead);//初始化

	SListPushBack(&pHead, 1);
	SListPushBack(&pHead, 2);
	SListPushBack(&pHead, 3);
	SListPushBack(&pHead, 4);
	SListPushBack(&pHead, 5);
	SListPushBack(&pHead, 6);
	SListPushBack(&pHead, 7);
	SListPrint(pHead);

	//ReverseList(&pHead);
	pHead = ReverseList_P(pHead);
	SListPrint(pHead);

}

void TestSList8()//冒泡排序
{
	PNode  pHead;//给出结点
	SListInit(&pHead);//初始化

	SListPushBack(&pHead, 1);
	SListPushBack(&pHead, 7);
	SListPushBack(&pHead, 5);
	SListPushBack(&pHead, 4);
	SListPushBack(&pHead, 3);
	SListPushBack(&pHead, 6);
	SListPushBack(&pHead, 9);
	SListPrint(pHead);

	BubbleSort(pHead);
	SListPrint(pHead);
}


void TestSList9()//寻找倒数第k个结点
{
	PNode  pHead,pNode;//给出结点
	SListInit(&pHead);//初始化
	SListPushBack(&pHead, 1);
	SListPushBack(&pHead, 2);
	SListPushBack(&pHead, 3);
	SListPushBack(&pHead, 4);
	SListPushBack(&pHead, 5);
	SListPushBack(&pHead, 6);
	SListPrint(pHead);

	pNode = FindLastKNode(pHead, 6);
	if (pNode)
	{
		printf("%d\n",pNode->_data);
	}
	DeleteLastKNode(&pHead, 6);
	SListPrint(pHead);

	DeleteLastKNode(&pHead, 2);
	SListPrint(pHead);

}



//////////讲解到2017.12.17   15:26

void TestSList10()
{
	PNode  pHead1, pHead2, pNewHead;//给出结点
	SListInit(&pHead1);//初始化
	SListPushBack(&pHead1, 1);
	SListPushBack(&pHead1, 3);
	SListPushBack(&pHead1, 5);
	SListPushBack(&pHead1, 7);
	SListPrint(pHead1);

	SListInit(&pHead2);//初始化
	SListPushBack(&pHead2, 2);
	SListPushBack(&pHead2, 4);
	SListPushBack(&pHead2, 4);
	SListPushBack(&pHead2, 6);
	SListPrint(pHead2);

	pNewHead = MergeLiist(pHead1, pHead2);
	SListPrint(pNewHead);
}

猜你喜欢

转载自blog.csdn.net/weixin_40123831/article/details/80496497