快速排序的改进
2015-03-20 17:41
239 查看
快速排序是用途最广的排序算法之一,但是在最坏的情况下快速排序会退化成直接插入排序时间复杂度也就将为了O(n^2).因此快速排序的改进也就是在选择key元素上的选择,选取一个中位数可以保证快速排序算法的效率。
改进方法:1.选取中卫数作为key
2.排序前可以先将key和最后一个元素交换,将key元素放到最后这样就可以减少一个比较的元素。
改进方法:1.选取中卫数作为key
2.排序前可以先将key和最后一个元素交换,将key元素放到最后这样就可以减少一个比较的元素。
#include<stdio.h> #include<stdlib.h> //选取枢轴,将所有元素小于它的移到它的左边,大于它的移到它的右边,返回它的位置. int partition(int A[],int low,inthigh) { if(A == NULL || low< 0 || high < 0 || low > high) //m>f>l { throw std::exception("invalidParameters!"); } //选取枢轴位置,取首元素,中间元素和末尾元素的中值作为枢轴 int mid = low+(high -low) >> 1; int firstElem = A[low]; int lastElem = A[high]; int midElem =A[mid]; int index = GetMiddleValue(A,low,high);//中位数的位置 //将枢轴元素放在第一个位置 if(index != low)//交换 { int temp =A[index]; A[index]= firstElem; A[low]= temp; } //定义两个标记,一个负责向后扫描,一个负责向前扫描 //向后每遇到一个比它大的就交换,向前扫描每遇到一个比它小的就交换 int x = A[low];//枢轴元素 int flagL =low; int flagH =high; while(flagL <flagH) { while(A[flagH] >= x &&flagL < flagH)//找到第一个比枢轴小的元素,放到当前flagL的位置 flagH--; if(flagL < flagH) A[flagL++] =A[flagH]; else break; while(A[flagL] <= x &&flagL < flagH)//找到第一个比枢轴大的元素,放到当前flagH的位置 flagL++; if(flagL <flagH) A[flagH--] =A[flagL]; else break; } A[flagL]= x; return flagL; } void qsort(int A[],intlow,int high) { if(low <high) { int k =partition(A,low,high); qsort(A,low,k-1); qsort(A,k+1,high); } } int main() { int A[] ={0, 10, -5, 7, 8, -18, 33}; qsort(A,0,sizeof(A)/sizeof(int)-1); for(int i=0;i<sizeof(A)/sizeof(int);i++) printf("%d ",A[i]); return 0; } //3值取中值 intGetMiddleValue(int A[],int low,int high) { int mid=low+(high-low)>>1; int y1=A[low]>A[mid]?low:mid; int y2=A[low]>A[high]?low:high; int y3=A[mid]>A[high]?mid:high; if (y1==y2) { return y3; } else return A[y1]>A[y2]?y2:y1; }