零、基本概念
1、排序算法的稳定性
假定在待排序的记录序列中,存在多个具有相同的关键字的记录,若经过排序,这些记录的相对次序保持不变,即在原序列中,r[i] = r[j]
,且r[i]
在 r[j]
之前,而在排序后的序列中,r[i]
仍在 r[j]
之前,则称这种排序算法是稳定的;否则称为不稳定的。
2、排序算法的排序方式
- in-place:可以理解为输出结果覆盖了输入:如输入vector a,最后返回的结果也是a,只不过a的值变了
- out-place:可以理解为输出结果并不是输入的那个变量:如输入vector a,最后返回的结果是vector b,而不是a这个变量自身
一、冒泡排序
1、算法步骤
-
比较相邻的元素。如果第一个比第二个大,就交换他们两个。
-
(内层循环)对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。这步做完后,最后的元素会是最大的数
-
(外层循环)除了最后一个元素,然后针对剩余的元素重复以上的步骤
-
持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。
2、算法实现
1)原始算法
void bubbleSort(vector<int>& arr){
//外层循环
for(int i = 0; i < arr.size() - 1; i++){
//内层循环
for(int j = 0; j < arr.size() - 1 - i; j++){
//如果前面的元素大于后面的元素,交换元素
if(arr[j] > arr[j + 1]){
swap(arr[j], arr[j + 1]);
}
}
}
}
- 外层循环中因为要用到
i + 1
,因此i
i的取值范围为[0, arr.size() - 1)
- 内层循环中
j
的范围要依赖于外层循环范围,取值范围为[0, arr.size() - 1 - i)
2)改良算法
改良一:使用一个变量记录当前轮次的比较是否发生过交换,如果没有发生交换表示已经有序,不再继续排序;
改良二:除了使用变量记录当前轮次是否发生交换外;再使用一个变量记录当前轮次比较中,最后一次发生交换的位置;下一轮排序时到达本轮最后交换的位置就停止。因为在本轮比较中,该位置后面就没有再交换了,说明后面都是有序的。
void bubbleSort(vector<int>&