这是我参与8月更文挑战的第28天,活动详情查看:8月更文挑战
交换排序
基本思想:
根据序列中两个元素关键字的比较结果来对换这两个记录在序列中的位置,从而最终保证整体有序
一、冒泡排序
假定排序表长为n,则基本思想为: ①从后往前(或者从前往后)两两比较元素的值,若为逆序则交换它们,直到序列比较完,称为一趟冒泡,结果会将最小元素排序完成
② 下一趟冒泡时,前一趟已确定的最小元素不再参与比较,其他元素继续按①执行交换,结果会将第2小的元素排序完成
③ 最多执行n-1趟排序,所有元素排好序
注意:
- 当某趟遍历时没有发生任何交换时,冒泡排序可提前结束
- 冒泡排序是稳定的排序算法
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)
- 最好时间复杂度:表本身已有序,只比较n-1次,不交换, 此时时间复杂度为O(n)
- 最坏时间复杂度:表逆序,需要比较n-1趟,第i趟排序要进 行n-i次比较+3(n-i)次交换
- 平均时间复杂度:也是𝑂(𝑛2).
- 注意:冒泡排序产生的有序子序列一定是全局有序的(不同于插入排序),这样每一趟排序都会有至少一个元素放在其最终的位置
二、快速排序
假定排序表长为n,则基本思想为:
① 在待排序表任取一个元素pivot作为基准,通过一趟排序将待排序表划分为独 立的两子表L[1,...,k-1]和L[k+1,...,n],使得L[1,...,k-1]中所有元素小于pivot,L[k+1,...,n]中所有元素大于或等于pivot
② 将pivot放在其最终的位置L[k]上,这是一趟排序
③ 下一趟排序时,递归的对两个子表重复上述过程,直到每部分都只有一个元素或为空为止,即所有元素放在其最终位置上