单链表快排

说到快速排序,基于数组时,我们一般使用两个指针,一个指向首元素,一个指向尾元素,通过这两个指针的移动和交换达到快排的目的,但是当基于单链表时,此方法就行不通了,因为单链表是单向的,只有后继指针,无前驱指针,只能向后遍历,不能向前遍历。那么基于单链表时到底应该怎样进行快速排序呢?本文针对于该问题给出具体的解决方法。

思路:定义两个指针pfirst和psecond,前者初始化为传入的头结点begin,后者初始为pfirst->pnext。pfirst始终指向遍历到目前为止的单链表中比基准值小的节点的组成的单链表的尾节点,当pfirst->mdata<base_key时,pfirst后移(pfirst=pfirst->pnext),交换这两个指针所指向的节点的元素值;psecond后移。即这两个指针均向右端移动,移动的过程中保持pfirst之前的key都小于选定的base_key,pfirst与psecond之间的key都大于选定的base_key,那么当psecond走到末尾时便完成了一趟快排。

以单链表元素{8,2,5,3,10,7}为例,进行一趟快排的详细过程如下:

代码实现:

#include<stdio.h>
#include<stdlib.h>
#include<algorithm>

typedef struct Node
{
	int mdata;
	struct Node* pnext;
}Node,*PNode;

void Init(PNode* phead)
{
	if (phead == NULL)
	{
		return;
	}
	*phead = NULL;
}
PNode BuyNode(ELEM_TYPE val)
{
	PNode pnewnode = (PNode)malloc(sizeof(Node));
	if (pnewnode == NULL)exit(0);
	pnewnode->mdata = val;
	pnewnode->pnext = NULL;
	return pnewnode;
}
bool InsertTail(Node** phead, ELEM_TYPE val)
{
	if (phead == NULL)
	{
		return false;
	}

	if (*phead == NULL)
	{
		PNode pnewnode = BuyNode(val);
		*phead = pnewnode;
		return true;
	}

	PNode pCur = *phead;
	while (pCur->pnext != NULL)
	{
		pCur = pCur->pnext;
	}

	PNode pnewnode = BuyNode(val);
	pCur->pnext = pnewnode;
	return true;
}
void Show(PNode phead)
{
	PNode pCur = phead;
	while (pCur != NULL)
	{
		printf("%d ", pCur->mdata);
		pCur = pCur->pnext;
	}
	printf("\n");
}
void quick_sort(PNode begin,PNode end)
{
	if (begin==NULL || end==NULL || begin==end)	return;
	
	PNode pfirst=begin;
	PNode psecond=pfirst->pnext;

	int base_key=begin->mdata;

	while(psecond!=NULL)
	{
		if(psecond->mdata<base_key)
		{
			pfirst=pfirst->pnext;
			std::swap(pfirst->mdata,psecond->mdata);
		}
		psecond=psecond->pnext;
	}
	std::swap(begin->mdata,pfirst->mdata);
	quick_sort(begin,pfirst);
	quick_sort(pfirst->pnext,end);
}

int main()
{
	PNode phead1;
	Init(&phead1);
	InsertTail(&phead1,8);
	InsertTail(&phead1,2);
	InsertTail(&phead1,5);
	InsertTail(&phead1,3);
	InsertTail(&phead1,10);
	InsertTail(&phead1,7);

	Show(phead1);
	PNode pb=phead1;
	PNode pe=phead1;
	while(pe->pnext!=NULL)
	{
		pe=pe->pnext;
	}
	quick_sort(pb,pe);
	Show(phead1);

	return 0;
}

运行结果如图:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值