链表分割问题

题目:编写代码,以给定的x为基准值将链表分割成两部分,所有小于x的结点排在大于或等于x的结点之前。

解法一:交换结点法,回想学习快速排序的时候,也是以基准值将一组数划分成两部分,小于基准值的排在前面,大于基准值的排在后半部分。因此解决这个问题也可以使用两个指针。如果链表头结点开始遍历,第一个需要移动的结点是第一个大于或等于基准值的结点,例如链表1->3->6->7->2->1->5,基准值设为4,那么第一个指针滑到6的时候应该停止,它需要被交换到后面,因为6前面的结点值都是小于基准值的,所以和它交换的结点应该在它后面,需要找到一个小于基准值的结点交换到前面去,于是找到了结点2。交换结点6和2。然后两个指针同时后移一位,在寻找需要交换的结点过程中指针一直滑到链表结尾时,表明链表中已经没有需要交换的结点,这时候直接返回,循环结束。

void Partition(ListNode* pHead, int n)
{
	if(pHead == NULL)
		return;
		
	ListNode *pCurr, *pNext;
	pCurr = pHead;
	while(pCurr->m_nValue < n)
	{
		pCurr = pCurr->m_pNext;
		if(pCurr == NULL)
			return;
	}
		
	pNext = pCurr;
	while(pNext->m_nValue >= n)
	{
		pNext = pNext->m_pNext;
		if(pNext == NULL)
			return;
	}
	
	while(pCurr != NULL && pNext != NULL)
	{
		while(pCurr->m_nValue < n)
		{
			pCurr = pCurr->m_pNext;
			if(pCurr == NULL)
				return;
		}
		
		while(pNext->m_nValue >= n)
		{
			pNext = pNext->m_pNext;
			//替换注释部分
			if(pNext == NULL)
				return;
		}
		
		int tmp = pCurr->m_nValue;
		pCurr->m_nValue = pNext->m_nValue;
		pNext->m_nValue = tmp;
		pCurr = pCurr->m_pNext;
		pNext = pNext->m_pNext;
	}
}
解法二:先分割再合并。创建两个链表,before和after,before保存小于基准值的结点,after保存大于或等于基准值的结点,最后将两个链表合并。

void Partition(ListNode** pHead, int n)
{
	if(pHead == NULL)
		return;
		
	ListNode *beforeHead, *beforeEnd, *afterHead;
	beforeHead = beforeEnd = afterHead = NULL;
	ListNode* pNode = *pHead;
	while(pNode != NULL)
	{
		ListNode* node = pNode->m_pNext;
		if(pNode->m_nValue < n)
		{
			if(beforeHead == NULL)
			{
				beforeHead = pNode;
				beforeEnd = pNode;
				beforeEnd->m_pNext = NULL;
			}
			else
			{
				pNode->m_pNext = beforeHead;
				beforeHead = pNode;
			}
		}
		else
		{
			if(afterHead == NULL)
			{
				afterHead = pNode;
				afterHead->m_pNext = NULL;
			}
			else
			{
				pNode->m_pNext = afterHead;
				afterHead = pNode;
			}
		}
		pNode = node;
	}
	if(beforeHead == NULL)
	{
		*pHead = afterHead;
		return;
	}
	beforeEnd->m_pNext = afterHead;
	*pHead = beforeHead;
}




发布了147 篇原创文章 · 获赞 18 · 访问量 20万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章