sougou校园招聘中某一道编程题
实现一个队链表排序的算法,C/C++可以使用std::list<int>,Java使用LinkedList<Integer>
要求先描述算法,然后再实现,算法效率尽可能高效。
/*
SortLinkList
对链表的排序操作
@author arhaiyun
date:2013/09/21
*/
#include "stdafx.h"
#include <iostream>
#include <time.h>
using namespace std;
typedef struct LinkNode
{
int m_nValue;
struct LinkNode* m_pNext;
}LinkNode, *LinkList;
//采用递归的方式合并两个有序的链表
LinkList MergeList(LinkList pHead1, LinkList pHead2)
{
if(pHead1 == NULL)
return pHead2;
if(pHead2 == NULL)
return pHead1;
LinkList pHead;
if(pHead1->m_nValue < pHead2->m_nValue)
{
pHead = pHead1;
pHead->m_pNext = MergeList(pHead1->m_pNext, pHead2);
}
else
{
pHead = pHead2;
pHead->m_pNext = MergeList(pHead1, pHead2->m_pNext);
}
return pHead;
}
//对链表的排序,采用快慢指针将链表分为长度相等的两部分(奇数时有一半多一),思想跟归并排序相同
LinkList SortLinkList(LinkList* pHead)
{
if(*pHead == NULL)
return NULL;
if((*pHead)->m_pNext == NULL)
return *pHead;
LinkList pHead1 = *pHead;
//链表前半部分
LinkList pPrev = *pHead;
LinkList pNext = (*pHead)->m_pNext;
while(pNext != NULL && pNext->m_pNext != NULL)
{
pPrev = pPrev->m_pNext;
pNext = pNext->m_pNext->m_pNext;
}
//链表后面一半pHead2
LinkList pHead2 = pPrev->m_pNext;
//链表前一半的结尾
pPrev->m_pNext = NULL;
//前后两部分分别进行排序
pHead1 = SortLinkList(&pHead1);
pHead2 = SortLinkList(&pHead2);
//有序两部分的合并
*pHead = MergeList(pHead1, pHead2);
return (*pHead);
}
void PrintList(LinkList pList)
{
while(pList != NULL)
{
cout<<pList->m_nValue<<"\t";
pList = pList->m_pNext;
}
cout<<endl;
}
//创建一个链表,采用随机数生存链表元素
LinkList CreateLinkList()
{
LinkNode* pList = new LinkNode();
pList->m_nValue = 0;
pList->m_pNext = NULL;
srand(time(0));
for(int i = 1; i < 11; i++)
{
LinkNode* pNode = new LinkNode();
pNode->m_nValue = rand()%100;
pNode->m_pNext = pList->m_pNext;
pList->m_pNext = pNode;
}
PrintList(pList);
return pList;
}
int main()
{
//
LinkList pList = CreateLinkList();
SortLinkList(&pList);
PrintList(pList);
system("pause");
return 0;
}