冒泡排序 及其两次优化

来源:互联网 发布:排序算法比较 编辑:程序博客网 时间:2024/06/05 14:24

冒泡排序 及其两次优化

1 冒泡排序:原版

第一次,最大的“上浮”到最上面

第二次:第2大的“上浮”到最上面

void bubble_sort(int *a, int n){    for(int i = 0; i < n - 1; ++i){ // 每趟排序,最大值“沉底”,所以共需n-1趟,        for(int j = 0; j < n - i - 1; ++j){ // 每趟排序中,从头开始,两两交换,后面有i个元素已“沉底”            if(a[j] > a[j+1]) swap(a[j], a[j+1]);        }    }}

2 第一次优化

当数组是已排序的,原版冒泡排序仍要遍历n2/2次。

加入标记,当发现数组已排序时,即内层循环没有发生交换时,证明数组已经有序,程序结束。

void bubble_sort2(int *a, int n){    bool exchange = false;    for(int i = 0; i < n - 1; ++i){ // 每趟排序,最小值“沉底”,所以共需n-1趟,        for(int j = 0; j < n - i - 1; ++j){ // 每趟排序中,从头开始,两两交换,后面有i个元素已“沉底”            if(a[j] > a[j+1]) {                swap(a[j], a[j+1]);                exchange = true;            }        }        if(!exchange) break;    }}

3 第二次优化

如果只有0,1元素,那么按照第一次优化的算法,仍然要遍历2n次。

因为内层循环长度的设定依据是:经过i排序后,数组的后i-1个元素是已排序好的;

但实际上i次排序的循环长度取决于i-1次排序时最后的交换位置。

例如:第i-1次排序后,最后交换位置是index,则表明index之后的元素都已经排好序。

#include <iostream>#include <algorithm>#include <cstdlib>using namespace std;void print_array(int *a, int from, int to){    for(int i = from; i <= to; ++i){        cout << a[i] <<" ";    }    cout << endl;}void bubble_sort3(int *a, int n){    bool exchange = false;    int index = 0; // 最后交换的位置    int mark = n - 1; // 标记内部循环的范围    for(int i = 0; i < n - 1; ++i){ // 每趟排序,最大值“沉底”,所以共需n-1趟,        for(int j = 0; j < mark; ++j){ // 每趟排序中,从头开始,两两交换,后面有i个元素已“沉底”            if(a[j] > a[j+1]) {                swap(a[j], a[j+1]);                exchange = true;                index = j;            }        }        if(!exchange) break;        mark = index;    }}int main(){    int n = 1000;    int K = 10;    int *a = new int[n];    for(int i = 0; i < n; ++i){        a[i] = rand() % n;    }    bubble_sort3(a, n);    print_array(a, 0, K-1);    return 0;}

附:测试程序

#include <iostream>#include <algorithm>#include <cstdlib>using namespace std;void print_array(int *a, int from, int to){    for(int i = from; i <= to; ++i){        cout << a[i] <<" ";    }    cout << endl;}void bubble_sort3(int *a, int n){    bool exchange = false;    int index = 0; // 最后交换的位置    int mark = n - 1; // 标记内部循环的范围    for(int i = 0; i < n - 1; ++i){ // 每趟排序,最大值“沉底”,所以共需n-1趟,        for(int j = 0; j < mark; ++j){ // 每趟排序中,从头开始,两两交换,后面有i个元素已“沉底”            if(a[j] > a[j+1]) {                swap(a[j], a[j+1]);                exchange = true;                index = j;            }        }        if(!exchange) break;        mark = index;    }}int main(){    int n = 1000;    int K = 10;    int *a = new int[n];    for(int i = 0; i < n; ++i){        a[i] = rand() % n;    }    bubble_sort3(a, n);    print_array(a, 0, K-1);    return 0;}
0 0
原创粉丝点击