快速排序 算法 详解 及 深度优化

下面简介经典算法  快速排序算法 实现及优化。 (欢迎大家指点,继续提出优化的方法,共同提高

基本思想:(以按从小到大排序为例说明)通过多次的排序,每次的排序均将要排序的数组分为两部分,前一部分均比中间值小,后一部分均比中间值大,这样重复递归下去将每一部分按相同的思路进行分割,最终使整个数组达到从小到大有序排列。

较冒泡排序的优点:同为通过不断的比较和移位来得到有序数组,但快排增大了比较和移动的距离,使关键字大的能从最前移到最后,关键字小的能从叫最后移到最前,从而减少了比较和移动的次数。


关键代码:
int Qsort(int arr[], int low, int high)//len不包括arr[0]
{
	int pivot;
	if (low < high)
	{
		pivot = Partition(arr, low, high);//分成两组
		Qsort(arr, low, pivot - 1);//数组 low~pivot-1 的元素均比pivot小
		Qsort(arr, pivot + 1, high); //数组 pivot+1~high 的元素均比pivot大
	}
	return 0;
}
int Partition(int arr[], int low, int high)
{
	int pivot = arr[low];
	while (low < high)
	{
		while(low < high && arr[high] >= pivot)
			high--;
		swap(arr, low, high);//处理数组的后部分,将比 pivot小的移到前面
		while(low < high && arr[low] <= pivot)
			low++;
		swap(arr, low, high); //处理数组的前部分,将比 pivot大的移到后面
	}  
	return low;//当low,high指向同一值时退出循环,此时low,high指向pivot
}
int swap(int arr[], int low, int high)
{
	int temp;
	temp = arr[low];
	arr[low] = arr[high];
	arr[high] = temp;

	return 0;
}
以上为 基本 快拍算法的实现。可通过下面测试验证:

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

int array[50] = {0,3,6, 7,6,8,23,46,8,23,75,23,11,84,2,56,32};
int Partition(int arr[], int low, int high);
int Qsort(int arr[], int low, int high);//len不包括arr[0]
int swap(int arr[], int low, int high);


int main()
{
	int i;
	int len = 20;
	Qsort(array, 1, len);
	for (i = 0; i <len; i++)
	{
		printf("%d ",array[i]);
	}

	return 0;
}

复杂度分析:

当选取的pivot为中间值时,递归树是平衡的,此时性能较好。因为分成的两端,在递归划分是能进行最少次数的划分。此时,复杂度为O(logn),而当 最坏的情况,即pivot为最大时,将出现极端情况,此时复杂度为O(n)。具体推到可参考其他资料~

优化:

1.优化选取的枢纽。避免出现极端情况

思想:选多个数,取中间值作为pivot 


2.优化不必要的交换

思想:arr[ow] = arr[high] 行,采用替换,而不是交换的方式进行优化。

int Partition(int arr[], int low, int high)
{
	int pivot = arr[low];

	while (low < high)
	{
		while(low < high && arr[high] >= pivot)
			high--;
		arr[low] = arr[high];
		while(low < high && arr[low] <= pivot)
			low++;
		arr[high] = arr[low];
	}
	arr[low] = pivot;  

	return low;
}

3.优化小数组排序方案

思想:快排适合 数组较大时的排序,较少时不如简单排序。

方案:Qsort()排序对数组大小进行判断,选择适当的排序。


4.优化递归操作

思想:过多递归占用大量堆栈,同时入栈退栈浪费大量时间,改为迭代

int Qsort(int arr[], int low, int high)//len不包括arr[0]
{
	int pivot;

	while (low < high)
	{
		pivot = Partition(arr, low, high);//分成两组
		Qsort(arr, low, pivot - 1);
		low = pivot + 1;
		//Qsort(arr, pivot + 1, high);
	}

	return 0;
}

讲解完毕。 欢迎大家提更多方案。





评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值