题目
代码实现冒泡排序,将线性表a按照从小到大的顺序进行排序。
实现代码
经典版:
void bubbleSort(vector<int>& a){
int n=a.size();
for(int i=0; i<n-1; i++)
for(int j=1; j<n; j++)
if(a[j-1]>a[j])
swap(a[j-1], a[j]);
}
优化版:
#include <vector>
#inlcude <algorithm>
void bubbleSort(vector<int>& a){
int n=a.size(); // 数组长度
bool sorted=false; // 整体排序完成标志(1->当前数组已完成排序)
while(!sorted){ // 排序完成前会一直进行循环
sorted=ture; // 假定已排序完成,若此趟扫描时排序未完成,会将其置为false
for(int i=1;i<n;i++)
if(a[i-1]>a[i]){ // 需要进行修改/此趟扫描时排序未完成
swap(a[i-1],a[i]);
sorted=false;
}
if(sorted) // 此趟扫描时排序已完成(即未出现需要交换的情况),退出函数
return;
n--; // 每趟扫描后最后一个元素必定就位,判断规模-1(下一趟只需调整[0,n-1])
}
}
分析
以上是经典的冒泡算法,不这里对其进行了两点小优化:
- 排序完成标志(sorted):添加了sorted变量记录此趟扫描中是否进行了修改, 即表示排序是否已经完成(此趟扫描不需要修改就代表排序已经完成)。通过sorted可以在排序完成后提前结束函数,而不是需要固定地执行完最坏情况下所需的n-1趟扫描。
- *规模调整(n–):用到了冒泡排序的一个特性——每趟扫描后末位元素一定已经归位。据此可以每趟扫描后都减小一位扫描的规模,以此减少部分多余的操作。
此外还有一个小细节:
- 比较时使用 > > >而不是 ⩾ \geqslant ⩾:此操作可以保证排序算法的稳定性,即不会对大小相同的元素进行多余的交换操作。