排序算法分析总结

Analysis of different sorting techniques

Bubble Sort

冒泡排序的算法时间复杂度是 n^2

Implementation:
// cpp
void bubble_sort(std::vector<int>& array) {
    int size = array.size();
    for (int i = size - 1; i > 0; --i) {
        for (int j = 0; j < i; ++j) {
            if (array[j] > array[j + 1]) {
                int tmp = array[j];
                array[j] = array[j + 1];
                array[j + 1] = tmp;
            }
        }
    }
}
Optimized Implementation:

The above function always runs O(n^2) time even if the array is sorted. It can be optimized by stopping the algorithm if inner loop didn’t cause any swap.

// cpp
// An optimized version of Bubble Sort
void bubble_sort(std::vector<int>& array) {
    int size = array.size();
    for (int i = size - 1; i > 0; --i) {
        bool swapped = false;
        for (int j = 0; j < i; ++j) {
            if (array[j] > array[j + 1]) {
                int tmp = array[j];
                array[j] = array[j + 1];
                array[j + 1] = tmp;
                swapped = true;
            }
        }
        // IF no two elements were swapped by inner loop, then break
        if (!swapped) break;
    }
}

Selection Sort

选择排序的时间复杂度为 O(n^2),但性能上略优于冒泡排序。
选择排序提高了冒泡排序的性能,它每遍历一次列表只交换一次数据,即进行一次遍历时找到最大(或最小)的项,完成遍历后,再把它换到正确的位置。和冒泡排序一样,第一次遍历后,最大(或最小)的项就已归位,第二次遍历次大(次小)项归位。这个过程持续进行,一共需要 n-1 次遍历来排好 n 个数,因为最后一个数必须在第 n-1 次遍历之后才能归位。

// cpp
void selection_sort(std::vector<int>& array) {
    int size = array.size();
    for (int i = size - 1; i > 0; --i) {
        int max_idx = i;
        for (int j = 0; j < i; ++j) {
            if (array[j] > array[max_idx])
                max_idx = j;
        }
        if (max_idx != i) {
            int tmp = array[i];
            array[i] = array[max_idx];
            array[max_idx] = tmp;
        }
    }
}

Insertion Sort

插入排序的算法时间复杂度仍然是 n^2,但其工作原理稍有不同。它总是保持一个位置靠前的已排好的子表,然后每一个新的数据项被 “插入” 到前边的子表里,排好的子表增加一项。我们认为只含有一个数据项的列表是已经排好的。每排后面一个数据(从 1 开始到 n-1),这 个的数据会和已排好子表中的数据比较。比较时,我们把之前已经排好的列表中比这个数据大的移到它的右边。当子表数据小于当前数据,或者当前数据已经和子表的所有数据比较了时,就可以在此处插入当前数据项。

// cpp
void insertion_sort(std::vector<int>& array) {
    int size = array.size();
    int i, key, j;
    for (i = 1; i < size; i++) {
        key = array[i];
        j = i - 1;
        while (j >= 0 && array[j] > key) {
            array[j + 1] = array[j];
            --j;
        }
        array[j + 1] = key;
    }
}

Shell Sort

shell_sort


视频来源:https://www.codingeek.com/algorithms/shell-sort-algorithm-explanation-implementation-and-complexity/

void shell_sort(std::vector<int>& array) {
    int size = array.size();
    for (int gap = size / 2; gap > 0; gap /= 2) {
        for (int i = gap; i < size; ++i) {
            int key = array[i];
            int j;
            for (j = i; j >= gap && array[j - gap] > key; j -= gap) {
                // 把较小的值往前移动,直到前面没有比它小的或取到子序列尾了
                int tmp = array[j];
                array[j] = array[j - gap];
                array[j - gap] = tmp;
            }
        }
    }
}

上面代码可以进行小优化:

void shell_sort(std::vector<int>& array) {
    int size = array.size();
    for (int gap = size / 2; gap > 0; gap /= 2) {
        for (int i = gap; i < size; ++i) {
            int key = array[i];
            int j;
            for (j = i; j >= gap && array[j - gap] > key; j -= gap)
                // 把较小的值往前移动,直到前面没有比它小的或取到子序列尾了
                array[j] = array[j - gap];
            array[j] = key;
        }
    }
}

Conclusion

前面说到,选择是冒泡的一种优化,但如果序列乱序较少,用冒泡本身的优化方法是最好的,效率更高。但选择,插入,冒泡复杂度都是n^2 所以基本不在这里面选择,重点应该比较的是堆排序,快排和归并排序。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值