7.交换排序——快速排序
2014-03-01 15:25
169 查看
本文针对交换排序中的快速排序。
快速排序是对冒泡排序的改进。
它引入枢轴的概念,可以任意选key数组中的一个值做枢轴,一般都取key[0],然后分别从高地址到低地址把小的数据放到小的位置;从低地址到高地址把大的数据放到大的位置,经过high-low+1次比较,使得high=low而且high处存放回key[0]数据,这就完成了依次划分(partition)操作,效果是high前的数据不比high处数据大,high后的数据都不比high处数据小,high处的数据就是最终完成时应该放的数据。
然后用递归的方法分别对低子表和高子表进行快速排序。
它的平均时间是knInn,n是记录个数,k是一个常数,而k是同数量级的排序中最小的,所以平均时间比之前的任何排序方法都快。
但是在最坏情况下,即序列已经逆序排放,这样快速排序就会退化成时间复杂度是O(n的平方)。改进的办法就是采用“三者取中法”,取第一个位置、最后一个位置、中间位置的数据中大小适中的那个和第一个位置的数据互换,然后再排,就可以极大改善时间消耗。当然还可以进一步改善的。
在空间上除了2路插入排序需要malloc一个数组外,其他都只需要不超过一个记录的空间;而快速排序需要栈来实现递归,所以在每一次划分后,如果能够取长度短的子序列先快速排序,就能降低栈的深度。
程序:
结果:
快速排序是对冒泡排序的改进。
它引入枢轴的概念,可以任意选key数组中的一个值做枢轴,一般都取key[0],然后分别从高地址到低地址把小的数据放到小的位置;从低地址到高地址把大的数据放到大的位置,经过high-low+1次比较,使得high=low而且high处存放回key[0]数据,这就完成了依次划分(partition)操作,效果是high前的数据不比high处数据大,high后的数据都不比high处数据小,high处的数据就是最终完成时应该放的数据。
然后用递归的方法分别对低子表和高子表进行快速排序。
它的平均时间是knInn,n是记录个数,k是一个常数,而k是同数量级的排序中最小的,所以平均时间比之前的任何排序方法都快。
但是在最坏情况下,即序列已经逆序排放,这样快速排序就会退化成时间复杂度是O(n的平方)。改进的办法就是采用“三者取中法”,取第一个位置、最后一个位置、中间位置的数据中大小适中的那个和第一个位置的数据互换,然后再排,就可以极大改善时间消耗。当然还可以进一步改善的。
在空间上除了2路插入排序需要malloc一个数组外,其他都只需要不超过一个记录的空间;而快速排序需要栈来实现递归,所以在每一次划分后,如果能够取长度短的子序列先快速排序,就能降低栈的深度。
程序:
#include <stdio.h> #include <stdlib.h> #define MAXSIZE 50 #define N 15 typedef struct{ int key; int other; }node; typedef struct { node array[MAXSIZE + 1]; int length; }list; //对l->array[low..high]作快速排序 void quicksort(list *l,int low,int high) { int pivot; if(low < high){ pivot = partition(l,low,high); if((high - pivot) > (pivot > low)){ quicksort(l,low,pivot - 1); //对低子表快速排序 quicksort(l,pivot + 1,high); //对高子表快速排序 } else{ quicksort(l,pivot + 1,high); //对高子表快速排序 quicksort(l,low,pivot - 1); //对低子表快速排序 } } } int partition(list *l,int low,int high) { int pivot; l->array[0] = l->array[low]; //选枢轴值并备份 pivot = l->array[low].key; while(low < high){ while(low < high && l->array[high].key >= pivot) --high; l->array[low] = l->array[high]; //高位置比枢轴值小的交换到低位置 while(low < high && l->array[low].key <= pivot) ++low; l->array[high] = l->array[low]; //低位置比枢轴值大的交换到高位置 } l->array[low] = l->array[0]; return low; //此时low = high } //打印序列 void print(list *l) { int i; for(i = 1;i <= l->length;i++) printf("%d %d\t",l->array[i].key,l->array[i].other); printf("\n"); } void main() { node data ={{5,6},{13,5},{22,2},{2,4},{6,5},{99,7},{6,15},{1,22},{15,12},{58,12},{48,40},{26,48},{38,35},{72,58},{61,22}}; list l; int i; for(i = 0;i < N;i++) l.array[i + 1] = data[i]; l.length = N; printf("befor sort:\n"); print(&l); quicksort(&l,1,N); printf("after quick sort:\n"); print(&l); }
结果:
[15:25:25]# ./c befor sort: 5 6 13 5 22 2 2 4 6 5 99 7 6 15 1 22 15 12 58 12 48 40 26 48 38 35 72 58 61 22 after quick sort: 1 22 2 4 5 6 6 15 6 5 13 5 15 12 22 2 26 48 38 35 48 40 58 12 61 22 72 58 99 7
相关文章推荐
- Java分别实现冒泡排序、插入排序、快速排序、选择排序、交换排序
- 排序算法系列-交换之快速排序
- 排序 - 交换排序 - 快速排序 (四)
- 排序算法(三)、交换排序 —— 冒泡排序 和 快速排序
- 交换类排序——快速排序
- Java实现交换排序之快速排序
- 归并排序,堆排序,基数排序,希尔排序,快速排序,交换排序,选择排序和插入排序的总结和比较
- 交换排序算法:快速排序-Quick Sort
- 【排序算法】 快速排序 quick sort(交换类排序)
- 交换排序------快速排序
- 1.交换两个数;2.求最大值;3.最大公约数;4.快速排序
- 常用排序算法实现[交换排序之冒泡排序、快速排序]
- #笔记#圣思园 JavaSE 第35讲——冒泡排序、交换排序、快速排序、二分查找
- 七大经典排序【 交换排序】之快速排序
- 快速排序,“两头交换”法 ,实现
- 排序算法(二)--交换排序之起泡排序,快速排序
- 交换排序--快速排序
- 两种常用的交换排序算法--冒泡排序、快速排序
- 六、内部排序综合(九种)—插入类排序(直接插入、折半插入、希尔排序);交换类排序(冒泡、快速);选择类排序(简单选择、堆排序);二路归并排序;基数排序
- 快速排序要交换等值元素的原因