排序添加

  • 插入排序
    最佳情况:T(n) = O(n)
    最坏情况:T(n) = O(n2)
    平均情况:T(n) = O(n2)
    public int[] insertionSort(int[] array) {
        if (array.length == 0) {
            return array;
        }
        int current;
        for (int i = 0; i < array.length - 1; i++) {
            current = array[i + 1];//从第二个元素开始,与之前的元素进行比较;之后的每个元素都做相同的操作
            int preIndex = i;//从当前元素开始比较
            while (preIndex >= 0 && current < array[preIndex]) {//如果preIndex元素比后一个元素大,就将preIndex元素移到下一位
                array[preIndex + 1] = array[preIndex];
                preIndex--;
            }
            array[preIndex + 1] = current;//前面做了--操作,避免越界-1以及补回多减掉的1,所以preIndex+1;把当前值的下一个赋到此处;如果current比它前面的所有值都大,位置就不变
        }
        return array;
    }
  • 归并排序
    最佳情况:T(n) = O(n)
    最差情况:T(n) = O(nlogn)
    平均情况:T(n) = O(nlogn)
    public int[] MergeSort(int[] array) {
        if (array.length < 2) return array;
        int mid = array.length / 2;//取中间索引
        int[] left = Arrays.copyOfRange(array, 0, mid);//将初始数组分为两个数组,第一次分解
        int[] right = Arrays.copyOfRange(array, mid, array.length);
        return merge(MergeSort(left), MergeSort(right));//递归分解,再合并;会一直分解到单个数为止,到那个时候,left和right的长度都为1
    }

    public int[] merge(int[] left, int[] right) {
        int[] result = new int[left.length + right.length];
        for (int index = 0, i = 0, j = 0; index < result.length; index++) {
            if (i >= left.length) {//如果左边left数组的值已经遍历完,那么result数组剩下的位置用right数组剩下的值来填
                result[index] = right[j++];
            } else if (j >= right.length) {//同理,如果right数组已经遍历完,就直接把left数组剩下的值来填result剩下的位置
                result[index] = left[i++];
            } else if (left[i] > right[j]) {
                result[index] = right[j++];//如果前面的两个都没满足,就需要比较当前left数组和right数组的当前值,谁小就把谁填进result
            } else {
                result[index] = left[i++];
            }
        }
        return result;
    }
  • 堆排序
    最佳情况:T(n) = O(nlogn)
    最差情况:T(n) = O(nlogn)
    平均情况:T(n) = O(nlogn)
    public int[] HeapSort(int[] array) {
        int len = array.length;
        if (len < 1) return array;
        //先构建一个大顶堆
        buildMaxHeap(array, len);

        for (int i = len - 1; i > 0; i--) {
            swap(array, 0, i);//把堆首和堆尾互换,此时堆尾成了最大
            len--;//长度减1
            adjustHeap(array, 0, len);//再调整
        }
        return array;
    }

    public void buildMaxHeap(int[] array, int len) {
        //从最后一个非叶子节点开始往上构造大顶堆
        //i的左子树和右子树分别为2i+1和2(i+1)
        for (int i = (len / 2 - 1); i >= 0; i--) {
            adjustHeap(array, i, len);
        }
    }

    public void adjustHeap(int[] array, int i, int len) {
        int maxIndex = i;
        int left = i * 2 + 1;
        int right = i * 2 + 2;
        //如果有左子树,并且左子树大于父节点,将最大指针指向左子树
        if (left < len && array[left] > array[maxIndex]) {
            maxIndex = left;
        }
        //如果有右子树,并且右子树大于父节点,将最大指针指向右子树
        if (right < len && array[right] > array[maxIndex]) {
            maxIndex = right;
        }
        //如果经过了上面的操作,即存在左子树或右子树大于父节点的情况,最大指针已经改变了
        if (maxIndex != i) {//调整当前小数(i,左,右)的值的位置,将最大的放到i位置
            swap(array, i, maxIndex);//那么就交换此时最大指针指向的值和当前i指向的值
            adjustHeap(array, maxIndex, len);//递归,对maxIndex做相同的操作
        }
    }

    public void swap(int[] array, int i, int j) {
        int temp = array[i];
        array[i] = array[j];
        array[j] = temp;
    }
posted @ 2021-03-29 22:47  shaon111  阅读(44)  评论(0)    收藏  举报