单链表面试题

1.//倒序打印链表

void ReversePrint(SListNode *pFirst);

有两种方法:

1.递归操作

2.非递归操作


void ReversePrint(SListNode *pFirst)
{   if(NULL == pFirst)  return;
//1递归
#if 0
	if(pFirst->pNext != NULL)
	{
		ReversePrint(pFirst->pNext);
	}
	printf(" %d ",pFirst->data);
	return;


#endif
//2 非递归
	SListNode *pEnd ;
	SListNode *pCur;
	pEnd = NULL;
	while (pFirst != pEnd)
	{
		
		for (pCur = pFirst; pCur->pNext != pEnd; pCur = pCur->pNext)
		{
		}
		pEnd = pCur;
		printf(" %d ", pEnd->data);
	}
	printf("\n");
}
2. //逆置链表

SListNode *ReverseList(SListNode *pFirst);


SListNode *ReverseList(SListNode *pFirst)
{
	if (NULL == pFirst)
	{
		return;
	}
	SListNode *pResult;
	SListInit(&pResult);

#if 0
	while (pFirst != NULL)
	{
		//头删
		SListNode *pDel;
		pDel = pFirst;
		pFirst = pFirst->pNext;
		//头插
		pDel->pNext = pResult;
		pResult = pDel;
	}

	SListPrint(pResult);
	return NULL;

#endif
	SListNode *p1, *p2, *p3;
	p1 = NULL; p2 = NULL; p3 = NULL;
	p2 = pFirst;
	while (p2)
	{
		p3 = p2->pNext;
		p2->pNext = p1;
		p1 = p2;
		p2 = p3;
	}
	pFirst = p1;
	SListPrint(pFirst);
	return NULL;
}
3.  //删除非尾无头单链表

void RemoveNodeNotTail(SListNode *pos);


void RemoveNodeNotTail(SListNode *pos)
{
	SListNode*pCur = pos->pNext;
	pos->data = pCur->data;
	pos->pNext = pCur->pNext;
	free(pCur);
}
4.//无头链表前插入一个结点

void InsertNoHead(SListNode*pos, int data);


void InsertNoHead(SListNode*pos, int data)
{
	SListNode*pNewNode = NULL;
	pNewNode = (SListNode*)malloc(sizeof(SListNode));
	pNewNode->data = pos->data;
	pNewNode->pNext = pos->pNext;
	pos->data = data;
	pos->pNext = pNewNode;
}

5.//约瑟夫环

SListNode * JocephCircle(SListNode*pFirst, int k);


SListNode * JocephCircle(SListNode*pFirst, int k)
{
	assert(pFirst);
	SListNode* pCur = NULL;
	pCur = pFirst;
	//1成环
	while (pCur->pNext != NULL)
	{
		pCur = pCur->pNext;
	}
	pCur->pNext = pFirst;
//2什么时候约瑟夫环停止(pFirst->pNext = pFirst);
	while (pFirst->pNext != pFirst)
	{
		int i;
		SListNode *pDel = NULL;
		for (i = 1; i < k; i++)
		{
			pCur = pCur->pNext;
		}
		pDel = pCur->pNext;
		pCur->pNext = pDel->pNext;
		free(pDel);
		pFirst = pCur->pNext;
	}
	printf("%d\n", pFirst->data);
	pFirst->pNext = NULL;
	SListPrint(pFirst);
	return NULL;
}

6.//冒泡排序

void BubbleSort(SListNode *pFirst);


void BubbleSort(SListNode *pFirst)
{
	if (NULL == pFirst)
	{
		return;
	}
	else
	{
		int flag = 0;
		SListNode * pTailNode = NULL;
		//当设置的尾节点与头结点指向同一个节点时,说明只有一个元素为排序,那么冒泡完成
		while (pTailNode != pFirst)
		{
			SListNode * pPreNode = pFirst;
			//每次参与比较的都是尾节点前面的结点
			while (pPreNode->pNext != pTailNode)
			{
				SListNode* pCurNode = pPreNode->pNext;
				if (pPreNode->data > pCurNode->data)
				{
					DataType dTemp = pPreNode->data;
					pPreNode->data = pCurNode->data;
					pCurNode->data = dTemp;
					flag = 1;
				}
				pPreNode = pPreNode->pNext;
			}
			//对冒泡的优化,只要有一趟比较没有发生结点交换,说明冒泡完成,就可以退出冒泡的代码块了
			if (0 == flag)
			{
				break;
			}
			pTailNode = pPreNode;
		}
	}
}
7.//遍历一遍找中间

SListNode *FindMid(SListNode*pFirst);


SListNode *FindMid(SListNode*pFirst)
{
	SListNode*pSlow = pFirst;
	SListNode*pFast = pFirst;
	while ((pFast->pNext != NULL)&&(pFast->pNext->pNext!=NULL))
	{
		
		pFast = pFast->pNext;
		pFast = pFast->pNext;
		pSlow = pSlow->pNext;
	}
	printf("%d\n", pSlow->data);
	return pSlow;
}
8//查找倒数第K个结点

SListNode *FindK(SListNode*pFirst, int k)


SListNode *FindK(SListNode*pFirst, int k)
{
	SListNode*pFast = NULL, *pSlow = NULL;
	pFast = pFirst;
	pSlow = pFirst;
	while (k)
	{
		pFast = pFast->pNext;
		k--;
	}
	while (pFast!= NULL)
	{
		pFast = pFast->pNext;
		pSlow = pSlow->pNext;
		
	}
	printf("%d\n", pSlow->data);
	return pSlow;

}

9.//删除倒数第k个结点

void RemoveK(SListNode *pFirst, int K)
{
	assert(pFirst);
	SListNode* pFast = pFirst;
	SListNode* pSlow = pFirst;
	SListNode* pPre = pFirst;

	if (NULL == pFirst || (K <= 0))
	{
		printf("K不合法!!!\n");
		return;
	}
	//让pFast先走K步
	while (K--)
	{
		//K大于链表中节点的个数
		if (NULL == pFast)
			return;
		pFast = pFast->pNext;
	}

	while (pFast)
	{
		pFast = pFast->pNext;
		pPre = pSlow;//pSlow在走之前,先保存,方便以后删除
		pSlow = pSlow->pNext;

	}

	//是第一个节点
	if (pSlow == pPre)
	{
		pFirst = pSlow->pNext;
		free(pSlow);
		return;
	}
	//不是第一个节点
	pPre->pNext = pSlow->pNext;
	free(pSlow);

}

10.//合并两个有序链表

SListNode *MergeOrderedList(SListNode*p1First, SListNode*p2First)
{
	SListNode*p1 = p1First;
	SListNode*p2 = p2First;
	SListNode*pNewNode = NULL;
	if (p1 == NULL)
	{
		return p2;
	}
	if (p2 == NULL)
	{
		return p1;
	}
	while ((p1 != NULL) && (p2 != NULL))
	{
		if ((p1->data) > (p2->data))
		{
			SListPushBack(&pNewNode, p2->data);
			p2 = p2->pNext;
		}
		if ((p1->data) < (p2->data))
		{
			SListPushBack(&pNewNode, p1->data);
			p1 = p1->pNext;
		}
	}
	while (p1)
	{
		SListPushBack(&pNewNode, p1->data);
		p1 = p1->pNext;
	}
	while (p2)
	{
		SListPushBack(&pNewNode, p2->data);
		p2 = p2->pNext;	
	}
	//SListPrint(pNewNode);
	return pNewNode;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值