漫画算法-小灰的算法之旅-排序算法(四)

本文内容基于《漫画算法 小灰的算法之旅》,魏梦舒著。


1. 分类

1.1 时间复杂度为O(n^2)的排序算法

1.2 时间复杂度为O(nlogn)的排序算法

1.3 时间复杂度为线性的排序算法

1.4 稳定性

1.5 本文中涉及的排序总结

2. 冒泡排序

2.1 思想

2.2 代码实现

2.3 代码优化1

2.4 代码优化2

2.5 代码优化3

3. 快速排序

3.1 思想

3.2 基准元素的选择

3.3 单边循环法

3.4 双边循环法

3.5 栈实现

4. 堆排序

4.1 思想

4.2 代码实现

5. 计数排序

5.1 思想

5.2 代码实现

5.3 局限性

6. 桶排序

6.1 思想

6.2 代码实现


1. 分类

1.1 时间复杂度为O(n^2)的排序算法

  • 冒泡排序
  • 选择排序
  • 插入排序
  • 希尔排序(略优于O(n^2),但又低于O(nlogn),姑且归入本类)

1.2 时间复杂度为O(nlogn)的排序算法

  • 快速排序
  • 归并排序
  • 堆排序

1.3 时间复杂度为线性的排序算法

  • 计数排序
  • 桶排序
  • 基数排序

1.4 稳定性

如果值相同的元素在排序后仍然保持着排序前的顺序,那么这种排序算法是稳定排序,反之是不稳定排序。

1.5 本文中涉及的排序总结

排序算法 平均时间复杂度 最坏时间复杂度 空间复杂度 稳定性
冒泡排序 O(n^2) O(n^2) O(1) 稳定
鸡尾酒排序 O(n^2) O(n^2) O(1) 稳定
快速排序 O(nlogn) O(n^2) O(logn) 不稳定
堆排序 O(nlogn) O(nlogn) O(1) 不稳定
计数排序 O(n+m) O(n+m) O(m) 稳定
桶排序 O(n) O(nlogn) O(n) 稳定

2. 冒泡排序

2.1 思想

把相邻的元素两两比较,当一个元素大于右侧相邻元素时,交换它们的位置,当一个元素小于或等于右侧相邻元素时,位置不变。

例如以下待排序序列:

  • 第1轮(详细)

  • 第2轮-第7轮

2.2 代码实现

public class SortTest {

    public static void bubbleSort(int[] array) {
        //-1是因为最后一轮不需要排序
        for (int i = 0; i < array.length - 1; i++) {
            //-i是因为每一轮都能确定排序好一个数
            for (int j = 0; j < array.length - i - 1; j++) {
                if (array[j] > array[j + 1]) {
                    //交换
                    int temp = array[j];
                    array[j] = array[j + 1];
                    array[j + 1] = temp;
                }
            }
        }
    }

    public static void main(String[] args) {
        int[] array = new int[]{5, 8 ,6, 3, 9, 2, 1, 7};

        bubbleSort(array);
        System.out.println(Arrays.toString(array));
    }
}

2.3 代码优化1

从上图中可以看出,第6轮排序后就已经是有序的了,可是算法还是进行了第7轮排序。

public class SortTest {

    public static void bubbleSort1(int[] array) {
        //-1是因为最后一轮不需要排序
        for (int i = 0; i < array.length - 1; i++) {
            boolean isSorted = true;
            //-i是因为每一轮都能确定排序好一个数
            for (int j = 0; j < array.length - i - 1; j++) {
                if (array[j] > array[j + 1]) {
                    //交换
                    int temp = array[j];
                    array[j] = array[j + 1];
                    array[j + 1] = temp;
                    //还在进行交换,表示未有序,还需要进行下一轮
                    isSorted = false;
                }
            }
            if (isSorted) {
                break;
            }
        }
    }

    public static void main(String[] args) {
        int[] array = new int[]{5, 8 ,6, 3, 9, 2, 1, 7};

        //bubbleSort(array);
        bubbleSort1(array);
        System.out.println(Arrays.toString(array));
    }
}

【注】因为序列原因,优化后的代码还是执行了7轮。作用情况是如果在第5轮结束的时候就已经有序了,那么程序只会进行到第6轮就停止,不会再进行第7轮,是这个意思。

2.4 代码优化2

参考以下待排序序列:

按照冒泡排序的思想,第1轮只会交换4和2、4和1的位置,第2轮只会交换3和2、3和1的位置...

说明的问题是:其实右边的许多元素已经是有序的了,但是程序不知道,他还是按照每一轮只会确定一个元素的顺序来执行,就造成了每一轮白白地比较了许多次。

public class SortTest {

    public static void bubbleSort2(int[] array) {
        //-1是因为最后一轮不需要排序
        int sortedBorder = array.length - 1;
        for (int i = 0; i < array.length - 1; i++) {
            boolean i
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值