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)。

  • 相关阅读:
    洛谷—— P3353 在你窗外闪耀的星星
    洛谷—— P1238 走迷宫
    洛谷—— P1262 间谍网络
    9.8——模拟赛
    洛谷—— P1189 SEARCH
    算法
    May 22nd 2017 Week 21st Monday
    May 21st 2017 Week 21st Sunday
    May 20th 2017 Week 20th Saturday
    May 19th 2017 Week 20th Friday
  • 原文地址:https://www.cnblogs.com/chenxianbin/p/11874236.html
Copyright © 2011-2022 走看看