二十七、快速排序

快速排序其实是逐次对每个基数进行排序,当达到一个临界值(也就是当元素个数达到一定数量时,简单的插入排序速度会大于快排)的时候就用插入排序来进行,其实这也是一个分治处理的过程,和归并思想大同小异,由于归并要进行多次递归,而快排基于基数每次进行线性时间的分组,所以理想情况下快排优于归并。这里就直接上代码。。。

#include <stdio.h>

//当剩余元素数较小时,简单的插入排序速度快于快速排序
#define CutOff 3

//打印数组
void PrintArray(int array[], int size)
{
	for(int i = 0; i < size; i++)
	{
		printf("%d\t", array[i]);
	}
	printf("\n");
}

//交换连个值
void Swap(int *i, int *j)
{
	(*i) = (*i) - (*j);
	(*j) = (*i) + (*j);
	(*i) = (*j) - (*i);
}

//插入排序
void InsertionSort(int array[], int size)
{
	int i, j, temp;
	for(i = 1; i < size; i++)
	{
		temp = array[i];
		for(j = i; j > 0 && array[j - 1] > temp; j--)
		{
			array[j] = array[j - 1];
		}
		array[j] = temp;
	}
}

//获取中值,先把最左边的值作为基准来比较为的是把最小值移到最左边,
//然后把最大值移到最右边,最后交换中值与最右边的值,形成分割雏形
int Median(int array[], int left, int right)
{
	int center = (left + right) / 2;
	if(array[left] > array[center])
	{
		Swap(&array[left], &array[center]);
	}
	if(array[left] > array[right])
	{
		Swap(&array[left], &array[right]);
	}
	if(array[center] > array[right])
	{
		Swap(&array[center], &array[right]);
	}
	//这么做是为了少一步交换大于中值的步骤
	Swap(&array[center], &array[right - 1]);
	//返回中值
	return array[right - 1];
}

//快速排序的组成部分
void QuickSortComponment(int array[], int left, int right)
{
	int leftPos, rightPos, pivot;
	if(right - left >= CutOff)
	{
		pivot = Median(array, left, right);
		leftPos = left;
		rightPos = right - 1;
		while(true)
		{
			while(array[++leftPos] < pivot){};
			while(array[--rightPos] > pivot){};
			if(leftPos < rightPos)
			{
				Swap(&array[leftPos], &array[rightPos]);
			}
			else
			{
				break;
			}
		}
		Swap(&array[leftPos], &array[right - 1]);
		QuickSortComponment(array, left, leftPos - 1);
		QuickSortComponment(array, leftPos + 1, right);
	}
	else
	{
		InsertionSort(array + left, right - left + 1);
	}
}

//快速排序
void QuickSort(int array[], int size)
{
	QuickSortComponment(array, 0, size - 1);
}

int main(void)
{
	int array[] = {2, 1, 4, 5, 0, 3, 6, 8, 7, 9};
	int size = sizeof(array)/sizeof(array[0]);
	QuickSort(array, size);
	PrintArray(array, size);
	return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值