【数据结构与算法】冒泡排序

冒泡排序:

时间复杂度:O(n^2)
空间复杂度:O(1)

测试:
10k 个随机数字排序:可以看到速度不分上下。

冒泡排序      : 	0.411331 s
冒泡排序优化1  : 	0.428745 s
冒泡排序优化2  : 	0.416507 s

10k 个接近有序数字排序:可以看到优化版的是速度快了一些。

冒泡排序       :       0.115256 s
冒泡排序优化1   :       0.000819 s
冒泡排序优化2   :       0.000736 s

基本思路:
两两比较,当前位置元素和下一个元素比较,大的放后面,小的放前面。
一轮比较完成后,最后一个元素即为最大元素。

void sort1(int arr[], int n) {
    for (int i = 0; i < n - 1; ++i) {
        for (int j = 0; j < n - 1 - i; ++j) {
            if (arr[j] > arr[j + 1]) {
                swap(arr[j], arr[j + 1]);
            }
        }
    }
}

优化 1:
某一次排序过后这个数组可能就已经有序了。
此时我们再进行一次循环,不发生交换,就说明已经有序了。

void sort2(int arr[], int n) {
    for (int i = 0; i < n - 1; ++i) {
        bool is_order = true;  // 假设已经有序
        for (int j = 0; j < n - 1 - i; ++j) {
            if (arr[j] > arr[j + 1]) {
                is_order = false;  // 发生元素交换,可能还是无序
                swap(arr[j], arr[j + 1]);
            }
        }
        if (is_order) {  // 如果有序就退出
            break;
        }
    }
}

优化 2:
排序区间判定。
对于 3 2 1 0 7 8 9,经过一次循环后变成 2 1 0 3 7 8 9,最后一次交换的位置就是无序区间。
记录每一轮的最后一次交换位置即可。

void sort3(int arr[], int n) {
    int sort_end = n - 1;
    int last_exchange = 0;
    for (int i = 0; i < n - 1; ++i) {
        bool is_order = true;
        for (int j = 0; j < sort_end; ++j) {
            if (arr[j] > arr[j + 1]) {
                is_order = false;
                last_exchange = j;
                swap(arr[j], arr[j + 1]);
            }
        }
        if (is_order) {
            break;
        }
        sort_end = last_exchange;
    }
}

EOF

发布了98 篇原创文章 · 获赞 91 · 访问量 4万+

猜你喜欢

转载自blog.csdn.net/Hanoi_ahoj/article/details/105472834
今日推荐