标签:
1、对于链表来说,由于其元素的访问只能是顺序访问,而快速排序是改进后的冒泡排序,需要随机存取数据,不合适。采用归并排序方式对链表元素进行访问;
2、需要的步骤
1) 分割:将一段链表分成两部分
2) 排序:将两端已经有序的链表合并
3)分治递归:递归操作
//将链表Plist分割,并把分割后的两段链表第一个元素节点通过二级指针带出。其中Plist为该链表第一个元素节点指针
void CLinkList::SplitList(CLinkNode * pList, CLinkNode **pBegNode1, CLinkNode **pBegNode2)
{
if (pList == NULL)
{
return;
}
CLinkNode *pFastNode = NULL;
CLinkNode *pSlowNode = pList;
if (pSlowNode == NULL || pSlowNode->pNext == NULL)
{
*pBegNode1 = pSlowNode;
*pBegNode2 = NULL;
return;
}
pFastNode = pSlowNode->pNext;
while (pFastNode != NULL)
{
pFastNode = pFastNode->pNext;
if (pFastNode != NULL)
{
pFastNode = pFastNode->pNext;
//只有当快指针满足向后移动的条件时,慢指针才跟着移动,否则会导致分割不均匀
pSlowNode = pSlowNode->pNext;
}
//printf("pSlowNode[%d], pFastNode[%d]\n", pSlowNode->Elem, pFastNode->Elem);
}
*pBegNode1 = pList;
*pBegNode2 = pSlowNode->pNext;
//printf("pList[%d], pSlowNode[%d]\n", pList->Elem, pSlowNode->Elem);
//从中间断开链表
pSlowNode->pNext = NULL;
}
//对两段有序链表进行排序
//通过虚拟节点进行
CLinkNode * CLinkList::SortList(CLinkNode * pListA, CLinkNode * pListB)
{
CLinkNode CTmpNode;
CTmpNode.pNext = NULL;
CLinkNode *pTmpNode = &CTmpNode;
if (pListA == NULL)
{
return pListB;
}
else if (pListB == NULL)
{
return pListA;
}
while (pListA != NULL && pListB != NULL)
{
if (pListA->Elem <= pListB->Elem)
{
pTmpNode->pNext= pListA;
pTmpNode = pTmpNode->pNext;
pListA = pListA->pNext;
}
else
{
pTmpNode->pNext= pListB;
pTmpNode = pTmpNode->pNext;
pListB = pListB->pNext;
}
}
if (pListA != NULL)
{
pTmpNode->pNext = pListA;
}
else if (pListB != NULL)
{
pTmpNode->pNext = pListB;
}
return CTmpNode.pNext;
}
//通过递归方式合并两个链表
CLinkNode * CLinkList::SortList1(CLinkNode * pListA, CLinkNode * pListB)
{
CLinkNode* pResult = NULL;
if (pListA == NULL)
{
return pListB;
}
else if (pListB == NULL)
{
return pListA;
}
//
if (pListA->Elem <= pListB->Elem)
{
pResult = pListA;
pResult->pNext = SortList1(pListA->pNext, pListB);
}
else
{
pResult = pListB;
pResult->pNext = SortList1(pListA, pListB->pNext);
}
return pResult;
}
//分治递归
//参数为out参数
void CLinkList::MergeSList(CLinkNode ** pListNode)
{
if (*pListNode == NULL || (*pListNode)->pNext == NULL)
{
return;
}
CLinkNode *pFrontNode = NULL;
CLinkNode *pBackNode = NULL;
//链表分割,因为不能随机访问
SplitList(*pListNode , &pFrontNode, &pBackNode);
//递归调用,递归到没有节点时退出
MergeSList(&pFrontNode);
MergeSList(&pBackNode);
//两个链表排序
*pListNode = SortList1(pFrontNode, pBackNode);
}
标签:
原文地址:http://blog.csdn.net/zhutianshidao1/article/details/51331682