快慢指针,链表的排序

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;
}



评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值