zoukankan      html  css  js  c++  java
  • 算法

    冒泡排序

    public static void bubbleSort(int[] arr) {
        if (arr == null || arr.length < 2) return;
        for (int i = arr.length - 1; i > 0; i--) {
            for (int j = 0; j < i; j++) {
                if (arr[j] > arr[j + 1]) {
                    swap(arr, j);
                }
            }
        }
    }
    

    冒泡排序比较简单,但是容易出现冗余的循环,即使是一个已经排序的数组传入仍然需要遍历 O(n ^ 2)。

    选择排序

    public static void selectSort(int[] arr) {
        if (arr == null || arr.length < 2) return;
        for (int i = 0; i < arr.length - 1; i++) {
            int min = i;
            for (int j = i + 1; j < arr.length; j++) {
                if (arr[min] > arr[j]) {
                    min = j;
                }
            }
            if (i != min) {
                swap(arr, i, min);
            }
        }
    }
    

    选择排序时间复杂度也是 O(n ^ 2)。

    插入排序

    public static void insertSort(int[] arr) {
        if (arr == null || arr.length < 2) return;
        for (int i = 1; i < arr.length; i++) {
            for (int j = i - 1; j >= 0 && arr[j] > arr[j + 1]; j--) {
                swap(arr, j, j + 1);
            }
        }
    }
    

    插入排序,有可能是 O(n) 也有可能是 O(n^2),和数据是否已经有序有关。

    希尔排序

    public static void shellSort(int[] array) {
        int gap = array.length;
        while (true) {
            if (gap == 1) {
                break;
            }
            gap /= 2;
            for (int i = gap; i < array.length; i++) {
                for (int j = i; j - gap >= 0; j = j - gap) {
                    if (array[j] < array[j - gap]) {
                        swap(array, j, j - gap);
                    }
                }
            }
        }
    }
    

    希尔排序的关键是步长的选择,时间复杂度为 O(n3/2)。

    归并排序

    public static void mergeSort(int[] arr) {
        if (arr == null || arr.length < 2) {
            return;
        }
        mergeSort(arr, 0, arr.length - 1);
    }
    
    
    public static void mergeSort(int[] arr, int l, int r) {
        if (l == r) {
            return;
        }
        int mid = l + ((r - l) >> 2);
        mergeSort(arr, l, mid);
        mergeSort(arr, mid + 1, r);
        merge(arr, l, mid, r);
    }
    
    public static void merge(int[] arr, int l, int m, int r) {
        //这个数组是临时生成的,使用过后又马上销毁,最大的长度为排序数组的长度,所以额外空间为 O(n)
        int[] helper = new int[r - l + 1];
        int i = 0;
        int p1 = l;
        int p2 = m + 1;
        while (p1 <= m && p2 <= r) {
            helper[i++] = arr[p1] < arr[p2] ? arr[p1++] : arr[p2++];
        }
        //下面两个循环有且只有一个会执行
        while (p1 <= m) {
            helper[i++] = arr[p1++];
        }
        while (p2 <= r) {
            helper[i++] = arr[p2++];
        }
        //需要注意 l 为归并的左边界,不是定值 0
        for (int j = 0; j < helper.length; j++) {
            arr[l + j] = helper[j];
        }
    }
    

    归并排序使用了递归的方式,利用 master 公式可以分析分治思路算法的时间复杂度。关于 master 公式可以参看这篇文章。归并排序使用了额外的存储空间,时间复杂度为 O(n * logn),空间复杂度为 O(n)。

  • 相关阅读:
    负margin在页面布局中的应用
    2018-05-04 圣杯布局 and 双飞翼布局,display:flex
    vue 动态加载图片路径报错解决方法
    vue 带参数的跳转-完成一个功能之后 之后需要深思,否则还会忘记
    vue项目打包后打开空白解决办法
    css 居中方法
    vue 不用npm下载安装包 该如何引用js
    安装WAMP 及 修改MYSQL用户名 、 密码
    Python 软件开发目录规范
    Python 1-3区分Python文件的两种用途和模块的搜索路径
  • 原文地址:https://www.cnblogs.com/chenxianbin/p/11874236.html
Copyright © 2011-2022 走看看