排序算法

1. 冒泡排序

 最基础排序,一句话总结冒泡排序,对于给定的数组,如果是升序排序,每一趟排序,都会把最大的元素放置在当前趟次的最后位置;

 冒泡排序,只会比较交换两个相邻的元素

 时间复杂度:严格O(N^2) ,和数据无关;

public static void bubbleSort(int[] arr) {
        if (arr == null || arr.length < 2) {
            return;
        }
        // details O(N^2) Deprecated
        // end is arr.length - 1 because exist of swap i++, prevent out of index error situation happen
        // outer foreach find one max num, and put it at end of arr array
        // inner foreach compare two nums and swap, util to the end of end border
        for (int end = arr.length - 1; end > 0; end--) {
            for (int i = 0; i < end; i++) {
                swap(arr, i, i + 1);
            }
        }
    }
private static void swap(int[] arr, int i, int j) {
    int tmp = arr[i];
    arr[i] = arr[j];
    arr[j] = tmp;
}

2. 选择排序

 最基础排序,一句话总结选择排序,对于给定的数组,如果是升序排序,每次选择最小的元素放置在当前次序的第一个位置;

  时间复杂度:严格O(N^2) ,和数据无关;

public static void selectionSort(int[] arr) {
        if (arr == null || arr.length < 2) {
            return;
        }
        // details O(N^2) Deprecated
        // first loop: search 0~ N-1, find min num and put it at 0 index
        // second loop: search 1~ N-1,find min num and put it at 1 index
        // until foreach all array
        for (int i = 0; i < arr.length - 1; i++) {
            int minIndex = i;
            for (int j = i + 1; j < arr.length; j++) {
                minIndex = arr[j] < arr[minIndex] ? j : minIndex;
            }
            swap(arr, i, minIndex);
        }
    }
private static void swap(int[] arr, int i, int j) {
        int tmp = arr[i];
        arr[i] = arr[j];
        arr[j] = tmp;
    }

3. 插入排序

基础排序,类似扑克牌,整体思路如下(升序排)

 1. 从第二个元素开始遍历,即index = 1,1个元素默认有序;

 2. 对于当前元素,如果前一个元素比当前元素小,那么交换,直到前面没有元素;

 3. 每次循环保证当前位置 i 之前的素有元素都是有序的;

时间复杂度:O(N^2)

 1. 最好情况:如果原始数据是升序,那么插入排序的时间复杂度是O(N),因为每次都不用发生交换动作;

 2. 最坏情况:如果原始数据是逆序,那么插入排序的时间复杂度是O(N^2) ,每次都要进行交换到第一个元素;

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

    private static void swap(int[] arr, int i, int j) {
        int tmp = arr[i];
        arr[i] = arr[j];
        arr[j] = tmp;
    }

4. 归并排序

public void mergeSort(int[] arr) {
        if (arr == null || arr.length < 2) {
            return;
        }
        process1(arr, 0, arr.length - 1);
    }

    private void process1(int[] arr, int start, int end) {
        if (start == end) {
            return;
        }
        int mid = start + (end - start) / 2;
        process1(arr, start, mid);
        process1(arr, mid + 1, end);
        merge(arr, start, mid, end);
    }

    private void merge(int[] arr, int start, int mid, int end) {
        int[] help = new int[end - start + 1];
        int index = 0;
        int p1 = start;
        int p2 = mid + 1;
        while (p1 <= mid && p2 <= end) {
            help[index++] = arr[p1] < arr[p2] ? arr[p1++] : arr[p2++];
        }
        while (p1 <= mid) {
            help[index++] = arr[p1++];
        }

        while (p2 <= end) {
            help[index++] = arr[p2++];
        }

        for (int i = 0; i < help.length; i++) {
            arr[start + i] = help[i];
        }
    }

5. 归并排序

public void quickSort(int[] arr) {
        if (arr == null || arr.length < 2) {
            return;
        }
        process(arr, 0, arr.length - 1);
    }

    private void process(int[] arr, int start, int end) {
        if (start >= end) {
            return;
        }
        swap(arr, new Random().nextInt(end - start + 1) + start, end);
        int[] bound = partition(arr, start, end);
        process(arr, start, bound[0] - 1);
        process(arr, bound[1] + 1, end);
    }

    private int[] partition(int[] arr, int start, int end) {
        if (start > end) {
            return new int[]{-1, -1};
        }
        if (start == end) {
            return new int[]{start, end};
        }

        int p1 = start - 1;
        int p2 = end;
        int index = start;
        while (index < p2) {
            if (arr[index] == arr[end]) {
                index++;
            } else if (arr[index] < arr[end]) {
                swap(arr, index++, ++p1);
            } else {
                swap(arr, index, --p2);
            }
        }
        swap(arr, p2, end);
        return new int[]{p1 + 1, p2};
    }

    public void swap(int[] arr, int x, int y) {
        int tmp = arr[x];
        arr[x] = arr[y];
        arr[y] = tmp;
    }

  

posted @ 2021-04-03 19:40  __Helios  阅读(106)  评论(0编辑  收藏  举报