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

来源:互联网 发布:衣柜 知乎 编辑:程序博客网 时间:2024/05/01 04:43

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

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

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


关键代码: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;}

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





原创粉丝点击