下面简介经典算法 快速排序算法 实现及优化。 (欢迎大家指点,继续提出优化的方法,共同提高)
基本思想:(以按从小到大排序为例说明)通过多次的排序,每次的排序均将要排序的数组分为两部分,前一部分均比中间值小,后一部分均比中间值大,这样重复递归下去将每一部分按相同的思路进行分割,最终使整个数组达到从小到大有序排列。
较冒泡排序的优点:同为通过不断的比较和移位来得到有序数组,但快排增大了比较和移动的距离,使关键字大的能从最前移到最后,关键字小的能从叫最后移到最前,从而减少了比较和移动的次数。
关键代码:
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;
}
讲解完毕。 欢迎大家提更多方案。