排序

不问归期 提交于 2020-01-12 13:45:39

总表

排序算法 平均复杂度 最优复杂度 最差情况的复杂度 稳定性 空间复杂
起泡排序 n2 n n2 稳定 1
插入排序 n2 n n2 稳定 插入排序
选择排序 n2 n2 n2 不稳定 1
希尔排序 n2 不稳定 1
快速排序 nlogn nlogn n2 不稳定 logn
堆排序 nlogn nlogn nlogn 不稳定 1
归并排序 nlogn nlogn nlogn 稳定 n
插入排序:

把整个序列分为有序的前半部分和无序的后半部分,每次从无序的后半部分取出第一个插入到有序部分中间

起泡排序:

每次比较相邻的两个元素,若前者较大则交换两个元素的顺序,每轮会把一个最大元素交换到最后的位置;

选择排序:

把整个序列分为有序的前半部分和无序的后半部分,每次从无序的后半部分选取最小元素插入到有序部分的末尾

快速排序:

每次以某个元素为界(一般是第一个元素)将整个序列按大小划分为两部分,然后递归地对左右两组元素做同样的事情

    void quickSort(int[] array, int start, int end) {
        if (start >= end) {
            return;
        }
        boolean order = true;
        int i = start;
        int j = end;
        while (i != j) {
            if (array[i] > array[j]) {
                int temp = array[j];
                array[j] = array[i];
                array[i] = temp;
                order = !order;
            }
            if (order) {
                i++;
            } else {
                j--;
            }
        }
        quickSort(array, start, i - 1);
        quickSort(array, i + 1, end);
    }
堆排序:

参考

	public static void sort(int[] arr) {
        for (int i = arr.length / 2 - 1; i >= 0; i--) {
            adjustHeap(arr, i, arr.length);
        }
        for (int j = arr.length - 1; j > 0; j--) {
            swap(arr, 0, j);
            adjustHeap(arr, 0, j);
        }

    }
	//i表示要对位置为i的节点进行位置调整以维持堆序性
	//length表示堆的大小,即数组未排序部分的长度
    public static void adjustHeap(int[] arr, int i, int length) {
        int temp = arr[i];										//先取出当前元素i
        for (int k = i * 2 + 1; k < length; k = k * 2 + 1) {	//从i结点的左子结点开始,也就是2i+1处开始
            if (k + 1 < length && arr[k] < arr[k + 1]) {		//如果左子结点小于右子结点,k指向右子结点
                k++;
            }
            if (arr[k] > temp) {								//如果子节点大于父节点,将子节点值赋给父节点
                arr[i] = arr[k];
                i = k;
            } else {
                break;
            }
        }
        arr[i] = temp;											//将temp值放到最终的位置
    }

    public static void swap(int[] arr, int a, int b) {
        int temp = arr[a];
        arr[a] = arr[b];
        arr[b] = temp;
    }
归并排序:
    void sort(int[] a, int low, int high) {
        int mid = (low + high) / 2;
        if (low < high) {
            sort(a, low, mid);
            sort(a, mid + 1, high);
            merge(a, low, mid, high);
        }
    }

    void merge(int[] a, int low, int mid, int high) {
        int[] temp = new int[high - low + 1];
        int i = low;
        int j = mid + 1;
        int k = 0;
        // 把较小的数先移到新数组中
        while (i <= mid && j <= high) {
            if (a[i] < a[j]) {
                temp[k++] = a[i++];
            } else {
                temp[k++] = a[j++];
            }
        }
        // 把左边剩余的数移入数组
        while (i <= mid) {
            temp[k++] = a[i++];
        }
        // 把右边边剩余的数移入数组
        while (j <= high) {
            temp[k++] = a[j++];
        }
        // 用temp中的数覆盖nums数组
        for (int x = 0; x < temp.length; x++) {
            a[x + low] = temp[x];
        }
    }
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!