一.改进冒泡排序
在冒泡排序中,记录的比较和移动是在相邻单元中进行的,记录每次交换只能上移或下移一个单元,因而总的比较次数和移动次数比较多。
改进的着眼点:
1.减少总的比较次数和移动次数
2.增大记录的比较和移动距离
3.较大记录从前面直接移动到后面;较小记录从后面直接移动到前面
二.快速排序的基本思想
首先选取一个轴值,通过一趟排序将待排序记录分割成独立的两部分,前一部分记录的关键码均小于或等于轴值,后一部分记录的关键吗均大于或等于轴值,然后分别对这两部分重复上述方法,直到整个序列有序。
三.需要解决的关键问题
1.如何选取轴值?
1)选取第一个元素
2)选取最后一个元素
3)选取第一个、最后一个、中间元素中值为中间的那个元素
2.如何实现分割(一次划分)?
设待划分的序列是r[s]~r[t],设参数i,j分别指向子序列左右两端的下标s和t,令r[s]为轴值。
1)j从后向前扫描,直到r[j]<r[s],将r[j]移动到r[i]的位置,使关键码小的记录移动到前面去
2)i从前向后扫描,直到r[i]>r[j],将r[i]移动到r[j]的位置,使关键码大的记录移动到后面去
3)重复上述操作,直到i=j
四.代码
int partition(int a[],int first,int end){int i=first,j=end,temp;while(i<j){while(i<j&&a[j]>=a[i]){--j;}if(i<j){temp=a[i];a[i]=a[j];a[j]=temp;}while(i<j&&a[j]>=a[i]){++i;}if(i<j){temp=a[i];a[i]=a[j];a[j]=temp;}}return i;//i==j时,返回轴值
}void quickSort(int a[],int first,int end){if(first<end){int pos=partition(a,first,end);quickSort(a, first, pos-1);quickSort(a, pos+1, end);}
}
五.时间性能分析
1)最好情况
每次轴值都能选取到最中间的元素
O(nlog2n)
2)最坏情况
每次都选取到最大/最小的元素
O(n^2)