32排序算法之快速排序
排序算法之快速排序
基本原理——反复进行有序划分。
有序划分方法
在数组a中任选一个元素x作为划分元素,通过比较将小于x的元素换到数组的左端(左段),
将大于或等于x的元素换到数组右端(右段),x本身位于两段之间。如果左、右段元素个数多于1,则递归的将左、右段各自划分,直到每段元素个数都不超过1,从而达到排序目的。
示例
递归的快速排序算法
划分函数partition完成对一个划分段的划分,返回划分元素最终位置。
递归函数qksort完成划分段的一对下标“配对”,调用partition对其划分。
主调语句:
qksort(a,0,n-1); //对数组a[n]排序
(1)划分函数
void partition(int a[ ],int s,int t,int &k)
{ int i,j,x;
x=a[s]; //取划分元素
i=s; j=t; //扫描指针初值
do //循环地进行划分
{ while((a[j]>=x)&&(i<j)) j- - ;
if(i<j) a[i++]=a[j];
while ((a[i]<x)&&(i<j)) i++;
if(i<j) a[j- -]=a[i];
}
while(i<j); //直到i等于j
a[i]=x; //划分元素就位
k=i;
}
(2)递归的处理函数
void qksort(int a[ ],int i,int j)
{ int k;
if(i<j)
{
partition(a,i,j,k); //划分
qksort(a,i,k-1); //递归
qksort(a,k+1,j); //递归
}
}
划分元素的选择方法:
1)首元素
2)选择“中值元素”
首元素a[s]、尾元素a[t]和中间位置的元素a[(s+t)/2],三者中“中间大小”的那个元素
3)随机元素
选择a[i],i 是划分段下标值s到t之间的一个随机数。当划分元素不是首元素,先与首元素交换,再划分。
最后
1)划分元素的选取是关键
2)输入数据次序越乱,划分元素值的随机性越好,排序速度越快
(不是自然排序)
3)无法保证子问题的大小完全平衡,最坏情况下,总是O(n2)的。
快速排序源代码: //4快速排序(挖坑填数) void QuickSort(int *arr,int left,int right) //传入左右下标 { int i=left,j=right; int p=(left+right)/2; //取中间的数 int temp=arr[p]; //存放要插入的数 while(i<j) //左右两边下标不相等 { if(arr[i]<temp) i++; else { arr[p]=arr[i]; p=i; }; if(arr[j]>temp) j--; else { arr[p]=arr[j]; p=j; }; }; arr[p]=temp; if(left<p) QuickSort(arr,left,i-1); if(p<right) QuickSort(arr,j+1,right); }; int main() { int arr[10]={3,5,8,2,4,13,9,1,16,7}; QuickSort(arr,0,9); for(int i=0;i<10;++i) printf("%d ",arr[i]); getchar(); return 0; }