冒泡排序
基本思想:从后往前比较相邻元素,把当前序列中最小的元素交换至最前面,去掉这个元素在剩下的序列中重复这个过程。
void BubbleSort(ElemType A[], int n)
{
for(i=0;i<n-1;i++){
flag=false;
for(j=n-1;j>i;j--)
if(A[j-1].key>A[j].key){
swap(A[j-1], A[j]);
flag=true;
}
if(flag==false)
return; //本趟遍历后没有发生交换,说明表已经有序
}
}
空间效率 O(1)
时间效率 O(n^2)
稳定
快速排序
基本思想:在待排序表L[1...n]中任取一个元素pivot作为基准,通过一趟排序,将排序表分为独立的两部分,小于pivot的L[1...k-1]和大于pivot的L[k+1...n]而pivot放在其最终的位置L[k],这称为一趟快速排序。然后分别递归对两个子表重复上述过程,直到每部分只有一个元素或为空为止。
void QuickSort(ElemType A[], int low, int high){
if(low<high){
int pivotpos=Partition(A, low, high);
QuickSort(A, low, pivotpos-1);
QuickSort(A, pivotpos+1, high);
}
}
"快速排序算法的关键在于划分操作"
"这里采用每次都以当前表中第一个元素作为基准来对表进行划分的方法"
int Partition(ElemType A[], int low, int high)
{
ElemType pivot=A[low];
while(low<high){
while(low<high&&A[high]>=pivot) --high;
A[low]=A[high]
while(low<high&&A[low]<=pivot) ++low;
A[high]=A[low];
}
A[low]=pivot;
return low;
}
空间效率 最坏O(n) 平均O(log2n)
时间效率
与划分是否对称有关
最坏情况:每次划分的两个区域都是n-1和0个元素(初始排序表基本有序或基本逆序) O(n^2)
最好情况:每次划分两个区域的大小都不大于n/2 O(nlog2n)
平均情况下的运行时间与其最佳情况接近
快速排序是所有内部排序算法中平均性能最好的
提高效率的方法:当递归过程中划分得到的子序列的规模较小时就不要再继续递归调用,而是直接采用直接插入排序;尽可能选取可将数据中分的pivot,比如从序列的头尾及中间选取三个元素,再取它们的中间值作为pivot,或随机从当前表中选取。
不稳定
若右端区间有两个关键字相同,且小于pivot,则在交换到左区间后,相对位置会发生变化。
网友评论