快速排序
来源:互联网 发布:网络优化课程 编辑:程序博客网 时间:2024/05/01 16:12
快速排序(Quicksort)是对冒泡排序的一种改进。它的基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。
快速排序是一种内部排序方法。也就是说快速排序的排序对象是读入内存的数据。
但是快速排序是一种不稳定的排序方法。简单地说,元素a1, a2的关键字有a1.key=a2.key,则不稳定的排序方法不能保证a1, a2在排序后维持原来的位置先后关系。
快速排序每次将待排序数组分为两个部分,在理想状况下,每一次都将待排序数组划分成等长两个部分,则需要logn次划分。而在最坏情况下,即数组已经有序或大致有序的情况下,每次划分只能减少一个元素,快速排序将不幸退化为冒泡排序,所以快速排序时间复杂度下界为O(nlogn),最坏情况为O(n^2)。在实际应用中,快速排序的平均时间复杂度为O(nlogn)。
参考不少资料算写完两个程序:
程序1
#include<stdio.h>void QuickSort(int e[],int low,int high){int i=low,j=high,temp=e[low];while(i<j){while(i<j&&e[j]>=temp)j--;e[i]=e[j];while(i<j&&e[i]<=temp)i++;e[j]=e[i];}e[i]=temp;if(low<i-1){QuickSort(e,low,i-1);}if(high>i+1){QuickSort(e,i+1,high);}}void main(){int array[100],a,len;char ch;printf("请输入待排数据(不超过100个),以空格间隔、回车键结束\n");for(a=0;;a++){scanf("%d%c",&array[a],&ch);if(ch==10)break;}printf("排序前:");len=a+1;//因为数组下表从0开始,所以数组长度为最大下标加1for(int i=0;i<len;i++)printf("%d ",array[i]);QuickSort(array,0,len-1);printf("\n排序后:");for(i=0;i<len;i++)printf("%d ",array[i]);printf("\n");}
程序2(参考《数据结构》(C语言版)):
// DataType.h 待排记录的数据类型#define MAXSIZE 20 //一个用作示例的小顺序的最大长度typedef int KeyType;//定义关键字类型为整数类型typedef int InfoType;//定义其他类型typedef struct{KeyType key;//关键字项InfoType otherInfo;//其他数据项}RedType; //记录类型typedef struct{RedType r[MAXSIZE+1];//r[0]闲置或用作哨兵单元int length;//顺序表的长度}SqList;//顺序表类型
/** *QuickSort *参考《数据结构》(C语言版) */#include<stdio.h>#include"DataType.h"int Partition(SqList &L,int low,int high){//交换顺序表L中子表r[low...high]的记录,枢轴记录到位,并返回其所在位置,//此时在它之前(后)的记录均不大(小)于它KeyType pivotKey; L.r[0]=L.r[low];//用子表的第一个记录作枢轴记录pivotKey=L.r[low].key;//枢轴记录关键字while(low<high){//从表的两端交替的向中间扫描while(low<high&&L.r[high].key>=pivotKey)--high;L.r[low]=L.r[high];while(low<high&&L.r[low].key<=pivotKey)++low;L.r[high]=L.r[low];}L.r[low]=L.r[0];return low;//返回枢轴位置}//Partitionvoid QSort(SqList &L,int low,int high){//对顺序表L中的子序列L.[low...high]作快速排序int pivotLoc;if(low<high){pivotLoc=Partition(L,low,high);//将L.[low...high]一分为二QSort(L,low,pivotLoc-1);QSort(L,pivotLoc+1,high);}}//QSortvoid QuickSort(SqList &L){//对顺序表L作快速排序QSort(L,1,L.length);}//QuickSortvoid print(SqList &L){int i;for(i=1;i<=L.length;i++){printf("(%d,%d)",L.r[i].key,L.r[i].otherInfo);}printf("\n");}//Print#define N 8 void main() { RedType d[N]={{49,1},{38,2},{65,3},{97,4},{76,5},{13,6},{27,7},{49,8}}; SqList l; int i; for(i=0;i<N;i++) l.r[i+1]=d[i]; l.length=N; printf("排序前:\n"); print(l); QuickSort(l); printf("排序后:\n"); print(l); }
快速排序需要一个栈空间来实现递归, 若每一趟排序都将记录序列均匀地分割成长度相接近的两个子序列,则栈的最大深度为[log2n]+1(以2为底)(包括最外层参量进栈),但是,若每趟排序之后,枢轴位置均偏向子序列的一端,则为最坏情况,栈的最大深度为n,如果 在一趟排序之后比较分割所得两部分的长度,且先对长度短的子序列中的记录进行快速排序,则栈的最大深度可降为O(logn)。
- 快速排序
- 快速排序
- 快速排序
- 快速排序!
- 快速排序
- 快速排序
- 快速排序
- 快速排序
- 快速排序
- 快速排序
- 快速排序
- 快速排序
- 快速排序
- 快速排序
- 快速排序
- 快速排序
- 快速排序
- 快速排序
- 性能诊断与调优之V$--V$SESSION_WAIT_HISTORY
- C++程序设计实验报告(八十四) --- 第十七周任务一
- 上拉电阻 下拉电阻 灌电流 拉电流
- sql server远程访问设置
- Linux mount/umount
- 快速排序
- ioremap_nocache函数说明
- (10) 使用Spring的注解方式实现AOP入门 以及 细节
- 验证二代身份证真假
- tar解压与压缩
- zip 和 unzip
- C#中实现三层架构
- rar 的用法
- js中var的作用