每日一题(92) - 快速排序

题目来自网络

题目(1):基于数组的快速排序

题目(2):基于链表的快速排序

----

题目(1):基于数组的快速排序

思路:使用分治的思想,先选择枢轴,之后执行一次划分,并把原序列划分两个子序列,之后递归处理。

代码:

int partition(int nArr[],int nStart,int nEnd)
{
	int nKey = nArr[nStart];
	while(nStart < nEnd)
	{
		while(nStart < nEnd && nArr[nEnd] >= nKey)
		{
			nEnd--;
		}
		nArr[nStart] = nArr[nEnd];
		while(nStart < nEnd && nArr[nStart] <= nKey)
		{
			nStart++;
		}
		nArr[nEnd] = nArr[nStart];
	}
	nArr[nStart] = nKey;
	return nStart;
}
void QSort(int nArr[],int nStart,int nEnd)
{
	if (nStart >= nEnd)
	{
		return;
	}
	int nLoc = partition(nArr,nStart,nEnd);
	QSort(nArr,nStart,nLoc - 1);
	QSort(nArr,nLoc + 1,nEnd);
}

void QSort(int nArr[],int nLen)
{
	assert(nArr != NULL && nLen > 0);
	QSort(nArr,0,nLen - 1);
}

题目(2)基于链表的快速排序

思路(1)改变结点的值,不破坏链表指向。

代码:

struct ListNode
{
	int m_nData;
	ListNode* m_pNext;
};

/*对区间[pStartNode,pEndNode - 1]之间的结点进行排序*/
ListNode* Partition(ListNode* pStartNode,ListNode* pEndNode)
{
	assert(pStartNode != NULL);
	int nKey = pStartNode->m_nData;
	ListNode* pSlow = pStartNode;//链表中结点个数大于等于2
	ListNode* pFast = pStartNode->m_pNext;
	while(pFast != pEndNode)
	{
		if (pFast->m_nData < nKey)
		{
			pSlow->m_nData = pFast->m_nData;
			if (pSlow->m_pNext == pFast)
			{
				pSlow = pSlow->m_pNext;
			}
			else
			{
				pSlow = pSlow->m_pNext;
				pFast->m_nData = pSlow->m_nData;
			}
		}
		pFast = pFast->m_pNext;
	}
	//返回分割点位置
	pSlow->m_nData = nKey;
	return pSlow;
}

void QSort(ListNode* pStartNode,ListNode* pEndNode)
{
	//没有待排序结点或只有一个结点,则可直接返回
	if (pStartNode == pEndNode || pStartNode->m_pNext == pEndNode)
	{
		return;
	}
	ListNode* pKeyPos = Partition(pStartNode,pEndNode);
	QSort(pStartNode,pKeyPos);
	QSort(pKeyPos->m_pNext,pEndNode);
}

思路(2)不改变结点的值,但改变链表指向。

代码:

struct ListNode
{
	int m_nData;
	ListNode* m_pNext;
};

//*对区间[pStartNode,pEndNode - 1]之间的结点进行排序*/
ListNode* Partition(ListNode* pStartNode,ListNode* pEndNode)
{
	assert(pStartNode != NULL);
	ListNode* pKeyNode = pStartNode;

	ListNode* pLessHead = NULL;
	ListNode* pLastLessList = NULL;
	ListNode* pLastGreatList = pStartNode;
	ListNode* pCur = pStartNode->m_pNext;
	while(pCur != pEndNode)
	{
		if (pCur->m_nData > pKeyNode->m_nData)
		{
			//插入大于枢轴的链表中
			pLastGreatList->m_pNext = pCur;
			pLastGreatList = pCur;
		}
		else
		{
			//插入小于枢轴的链表中
			if (pLastLessList == NULL)
			{
				pLessHead = pCur;
				pLastLessList = pCur;
			}
			else
			{
				pLastLessList->m_pNext = pCur;
				pLastLessList = pCur;
			}
		}
		pCur = pCur->m_pNext;
	}
	//两个链表拼接在一起
	if (pLessHead != NULL)
	{
		pLastLessList->m_pNext = pKeyNode;
	}
	else
	{
		pLessHead = pKeyNode;
	}
	pLastGreatList->m_pNext = pEndNode;
	//返回第一个结点的地址
	return pLessHead;
}

ListNode* QSort(ListNode* pStartNode,ListNode* pEndNode)
{
	ListNode* pHead = NULL;
	//没有待排序结点或只有一个结点,则可直接返回
	if (pStartNode == pEndNode || pStartNode->m_pNext == pEndNode)
	{
		return pStartNode;
	}
	ListNode* pNewHead = Partition(pStartNode,pEndNode);
	pHead = QSort(pNewHead,pStartNode); //此链表第一个结点的地址是链表的首地址,需要返回
	pStartNode->m_pNext = QSort(pStartNode->m_pNext,pEndNode);//此链表第一个结点的地址应该放入枢轴的next中
	return pHead;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值