插入排序、冒泡排序、选择排序被我们老师成为三大傻瓜排序,当然了这三个排序虽然很笨重,但有时候却是最优秀的排序,对于新手来说,这也是非常好的入门算法。
插入排序:
步骤:
1、选择第二个元素(也可以从后往前选择)
2、在前面已排好的序列中选择适当的位置插入其中。适当的位置:即比前者小,比后者大(递增)
3、选择下一个元素,重复步骤2,直到完成所有元素的遍历。
代码:
template <typename E>
void inssort(E A[], int n){
for(int i = 1; i<n; i++){
for(int j = i; j > 0; j--){
if(A[j] < A[j-1]) Swap(A, j, j-1);
else break;
}
}
}
void Swap(E *A, int x, int y){
E temp = A[y];
A[y] = A[x];
A[x] = temp;
}
分析:
Best case:0 swaps, n-1 comparisons
Worst case:n(n-1)/2 swaps and comparisons
Average case: n(n-1)/4 swaps and comparisons
此外,这个算法有一个可以优化的地方,就是在将一个数字插入已经排序好的序列中的时候可以尝试使用二分法。
冒泡排序:(我们老师最嫌弃的算法,当然,他也相信我们可以写出更烂的,嗯,我也相信我自己)
步骤:
1、选择最后一个元素
2、将其与前一个元素比较
3、若后者比前者小,则交换位置,否则不交换(升序的方式)。最后将未排序的序列中的最小值排到未排序的序列前
4、重复步骤1、2、3,直到所有的序列都排好序。
代码:
template <typename E>
void bubsort(E A[], int n){
for(int i = 0; i<n-1; i++){
for(int j = n; j > i; j--){
if(A[j] < A[j-1]) Swap(A, j, j-1); //Swap函数在上面
}
}
}
分析:
Best case:0 swaps, n(n-1)/2 comparisons
Worst case:n(n-1)/2 swaps and comparisons
Average case:n(n-1)/4 swaps and n(n-1)/2 comparisons
我们老师之所以讨厌这个算法,是因为就算是在最好的情况下,即序列已经全部排好了都需要进行n(n-1)/2次的比较
选择排序:
步骤:
1、从第一个元素开始
2、未排序序列的第一个元素
3、将其依次从后往前比较,当后者比前者大的时候,交换二者;否则不交换。(升序)直到遍历未排序序列。
4、重复步骤2、3,直到未排序的序列的第一个元素为整个序列的最后一个元素。
代码:
template <typename E>
void selsort(E A[], int n){
for(int i = 0; i<n-1; i++){
int minindex = i;
for(int j = n-1; j>i; j--)
if(A[j] < A[minindex]) minindex = j;
Swap(A, i, minindex);
}
}
分析:
1、Best case:0 swaps, n(n-1)/2 comparisons
2、Worst case:n-1swaps ,n(n-1)/2comparisons
3、Average case:O(n)swaps,n(n-1)/2 comparisons
注:以上代码右本人打出来,再参照《数据结构与算法分析(C++版)(第三版)》Clifford A.Shaffer著,请选择性参考