数据结构《排序》

文章目录


什么是稳定什么是不稳定

相对次序不变则稳定,相对次序改变则不稳定

一、插入排序

1.1 直接插入排序

核心就是找到i下标的数在前面的数组中应该放的位置,i在往后走的过程中,i前面的数组已经是拍好序的了

java 复制代码
/**
     * 排序方式:直接插入排序
     * 时间复杂度:O(n^2),但当数据趋于有序时,比如有序数组,那么时间复杂度为O(n)
     * 稳定性:稳定
     * @param array
     */
    public static void insertSort(int[] array){
        for(int i = 1; i < array.length; i++){
            int tmp = array[i];
            int j = i - 1;
            for (; j >= 0; j--) {
                if(array[j] > tmp){
                    array[j + 1] = array[j];
                }else {
                    array[j + 1] = tmp;
                    break;
                }
            }
            //走到这有两种可能,一种是已经将tmp放到正确的位置了
            //一种是j到了-1的位置说明tmp是最小值,要将0位置的值改成tmp
            array[j + 1] = tmp;
        }
        System.out.println("直接插入排序");
    }



1.2 希尔排序

核心在于将数组分成一个一个的组,在组内进行直接插入排序,当gap越来越趋于1时,说明数组也在慢慢趋于有序

java 复制代码
/**
     * 排序方式:希尔排序
     * 时间复杂度:根据不同的gap时间复杂度不同,可以粗略理解为O(n^1.25)
     * 稳定性:不稳定
     * @param array
     */
    public static void shellSort(int[] array){
        int gap = array.length;
        while (gap > 1){
            gap = gap/3 +1;
            shellSortReal(array,gap);
        }
        System.out.println("希尔排序");

    }

    private static void shellSortReal(int[] array,int gap) {
        for (int i = gap; i < array.length; i++) {
            int tmp = array[i];
            int j = i - gap;
            for (; j >= 0; j -= gap) {
                if(array[j] > tmp){
                    array[j + gap] = array[j];

                }else {
                    array[j + gap] = tmp;
                    break;
                }
            }
            array[j + gap] = tmp;
        }
    }



二、选择排序

2.1 直接选择排序

核心要点就是从两边往中间逼近,在左右的范围中找到最大的数和最小的数,并将它们分别放在最右边和最左边

java 复制代码
/**
     * 排序方式:直接选择排序
     * 时间复杂度:O(n^2)
     * 稳定性:不稳定
     * @param array
     */
    public static void selectSort(int[] array){
        int left = 0;
        int right = array.length - 1;
        while (left < right){
            int minIndex = left;
            int maxIndex = left;
            for (int i = left; i <= right; i++) {
                if(array[i] < array[minIndex]){
                    minIndex = i;
                }
                if(array[i] > array[maxIndex]){
                    maxIndex = i;
                }
            }
            swap(array,minIndex,left);
            if(maxIndex == left) {//预防出现最大值在left位置,然后left的最大值被换到了minIndex位置
                maxIndex = minIndex;
            }
            swap(array,maxIndex,right);
            left++;
            right--;
        }
        System.out.println("直接选择排序");

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



2.2 堆排序

需要注意的是排升序要建大堆,排降序建小堆。

有关大小根堆的相关内容,我在《优先队列||堆》这篇文章中有介绍,有需要可以去看看,这里我们直接就用创建大根堆的代码不再解释了。

思路:将传入的数组组成大根堆,然后将堆顶元素和最后一个元素end所在指向的元素交换一下,这样数组最后一个元素就是最大的,再将换后的数组重新按堆排序,同时end--,找到倒数第二大的数,以此类推,直到end == 0

java 复制代码
/**
     * 排序方式:堆排序
     * 时间复杂度:O(N * log2(N))
     * 稳定性:不稳定
     * @param array
     */
    public static void heapSort(int[] array){
        createHeap(array);
        int end = array.length - 1;
        while (end >= 0){
            swap(array,end,0);
            siftDown(array,0,end);//确保顶为最大值
            end--;
        }
        System.out.println("堆排序");
    }

    private static void createHeap(int[] array) {
        for(int parent = (array.length - 2) / 2; parent >= 0; parent--){
            siftDown(array,parent,array.length);
        }
    }

    private static void siftDown(int[] array,int parent, int length) {
        int child = 2 * parent + 1;
        while (child < length){
            if(child + 1 < length && array[child] < array[child + 1]){
                child++;
            }
            if(array[child] > array[parent]){
                swap(array,child,parent);
                parent = child;
                child = 2 * parent + 1;
            }else {
                break;
            }
        }
    }



三、交换排序

3.1 冒泡排序

冒泡排序都不陌生了,这里就不多赘述了

java 复制代码
/**
     * 排序方式:冒泡排序
     * 时间复杂度:O(n^2)
     * 稳定性:稳定
     * @param array
     */
    public static void bubbleSort(int[] array){
        for (int i = 1; i < array.length; i++) {//第几次比较
            boolean flag = true;
            for (int j = 0; j < array.length - i; j++) {
                if(array[j] > array[j+1]){
                    swap(array,j,j+1);
                    flag = false;
                }

            }
            if(flag){
                break;
            }
        }
        System.out.println("冒泡排序");
    }

3.2 快速排序

思路:在数组中确定一个值,将这个数放到一个位置,通过调整这个数组,使得在这个数的左边所有数全部比它小,右边全都比它大,再以这个数的位置作为分界点,去看左半部分和右半部分,最后整个数组有序

hoare法
思路:以左边的数为基准,从右往左走,找比它小的,从左往右走找比它大的,然后两者位置交换

java 复制代码
/**
     * 排序方式:快速排序
     * 时间复杂度:O(Nlog2(N))
     * 稳定性:不稳定
     * @param array
     */
private static void quickSortTree(int[] array, int left, int right) {
        if(left >= right){
            return;
        }
        int pivo = partitionHoare(array,left,right);
        quickSortTree(array,left,pivo - 1);
        quickSortTree(array,pivo + 1,right);
    }
private static int partitionHoare(int[] array, int left, int right) {
        int tmp = array[left];
        int sleft = left;
        while (left < right){
            while (left < right && array[right] >= tmp){//一直往左走,直到遇到比tmp小的数
                right--;
            }
            while (left < right && array[left] <= tmp){//一直往左走,直到遇到比tmp大的数
                left++;
            }
            swap(array,left,right);
        }
        swap(array,sleft,left);
        return left;
    }



基于上面的代码进行的改进,只是理解过程的话,上面的就够了

优化版(进行了一些提升)

java 复制代码
/**
     * 排序方式:快速排序
     * 时间复杂度:O(Nlog2(N))
     * 稳定性:不稳定
     * @param array
     */
    public static void quickSort(int[] array){
        int left = 0;
        int right = array.length - 1;
        quickSortTree(array,left,right);
        System.out.println("快速排序");
    }


    private static void quickSortTree(int[] array, int left, int right) {
        if(left >= right){
            return;
        }
        if(right - left + 1 <= 10){//此时说明这个数组很小,如果经历了很多此递归,也已经趋于有序,用直接插入排序可以更快些
            insertSortRange(array,left,right);
            return;
        }

        int midIndex = getMidIndex(array,left,right);//将中间的数,最左边的数和最右边的数比较一下,找到最小的给左边的位置,这样在后序的
                                                    //的交换中,可以更快的将数组排好,因为数组更加趋于整齐了。
        swap(array,left,midIndex);

        int pivo = partitionHoare(array,left,right);
        quickSortTree(array,left,pivo - 1);
        quickSortTree(array,pivo + 1,right);
    }

    private static int getMidIndex(int[] array, int left, int right) {
        int mid = (right - left) / 2;
        if(array[left] < array[right]){//左边的小于右边
            if(array[right] < array[mid]){
                return right;//说明右边的最小
            }else {
                return mid;//说明中间的最小
            }
        }else {//右边的小于等于左边
            if(array[left] < array[mid]){
                return left;//说明左边的最小
            }else {
                return mid;//说明中间的最小
            }
        }
    }

    private static void insertSortRange(int[] array, int left, int right) {
        for(int i = left + 1; i <= right; i++){
            int tmp = array[i];
            int j = i - 1;
            for (; j >= 0; j--) {
                if(array[j] > tmp){
                    array[j + 1] = array[j];

                }else {
                    array[j + 1] = tmp;
                    break;
                }
            }
            array[j + 1] = tmp;
        }
    }

private static int partitionHoare(int[] array, int left, int right) {
        int tmp = array[left];
        int sleft = left;
        while (left < right){
            while (left < right && array[right] >= tmp){//一直往左走,直到遇到比tmp小的数
                right--;
            }
            while (left < right && array[left] <= tmp){//一直往左走,直到遇到比tmp大的数
                left++;
            }
            swap(array,left,right);
        }
        swap(array,sleft,left);
        return left;
    }



挖坑法
与hoare法不同的是,它不是交换,而是直接覆盖

java 复制代码
public static void quickSort(int[] array){
        int left = 0;
        int right = array.length - 1;
        quickSortTree(array,left,right);
        System.out.println("快速排序");
    }


    private static void quickSortTree(int[] array, int left, int right) {
        if(left >= right){
            return;
        }
        if(right - left + 1 <= 10){//此时说明这个数组很小,如果经历了很多此递归,也已经趋于有序,用直接插入排序可以更快些
            insertSortRange(array,left,right);
            return;
        }

        int midIndex = getMidIndex(array,left,right);//将中间的数,最左边的数和最右边的数比较一下,找到最小的给左边的位置,这样在后序的
                                                    //的交换中,可以更快的将数组排好,因为数组更加趋于整齐了。
        swap(array,left,midIndex);

        int pivo = partitionPothole(array,left,right);
        quickSortTree(array,left,pivo - 1);
        quickSortTree(array,pivo + 1,right);
    }

    private static int getMidIndex(int[] array, int left, int right) {
        int mid = (right - left) / 2;
        if(array[left] < array[right]){//左边的小于右边
            if(array[right] < array[mid]){
                return right;//说明右边的最小
            }else {
                return mid;//说明中间的最小
            }
        }else {//右边的小于等于左边
            if(array[left] < array[mid]){
                return left;//说明左边的最小
            }else {
                return mid;//说明中间的最小
            }
        }
    }

    private static void insertSortRange(int[] array, int left, int right) {
        for(int i = left + 1; i <= right; i++){
            int tmp = array[i];
            int j = i - 1;
            for (; j >= 0; j--) {
                if(array[j] > tmp){
                    array[j + 1] = array[j];

                }else {
                    array[j + 1] = tmp;
                    break;
                }
            }
            array[j + 1] = tmp;
        }
    }
    private static int partitionPothole(int[] array, int left, int right) {
        int tmp = array[left];
        while (left < right){
            while (left < right && array[right] >= tmp){//一直往左走,直到遇到比tmp小的数
                right--;
            }
            array[left] = array[right];//将这个小的数放到左边去
            while (left < right && array[left] <= tmp){//一直往左走,直到遇到比tmp大的数
                left++;
            }
            array[right] = array[left];//将这个大的数放到右边去
        }
        array[left] = tmp;
        return left;
    }

前后指针法

java 复制代码
public static void quickSort(int[] array){
        int left = 0;
        int right = array.length - 1;
        quickSortTree(array,left,right);
        System.out.println("快速排序");
    }


    private static void quickSortTree(int[] array, int left, int right) {
        if(left >= right){
            return;
        }
        if(right - left + 1 <= 10){//此时说明这个数组很小,如果经历了很多此递归,也已经趋于有序,用直接插入排序可以更快些
            insertSortRange(array,left,right);
            return;
        }

        int midIndex = getMidIndex(array,left,right);//将中间的数,最左边的数和最右边的数比较一下,找到最小的给左边的位置,这样在后序的
                                                    //的交换中,可以更快的将数组排好,因为数组更加趋于整齐了。
        swap(array,left,midIndex);

        int pivo = partitionFastAndSlowPoint(array,left,right);
        quickSortTree(array,left,pivo - 1);
        quickSortTree(array,pivo + 1,right);
    }

    private static int getMidIndex(int[] array, int left, int right) {
        int mid = (right - left) / 2;
        if(array[left] < array[right]){//左边的小于右边
            if(array[right] < array[mid]){
                return right;//说明右边的最小
            }else {
                return mid;//说明中间的最小
            }
        }else {//右边的小于等于左边
            if(array[left] < array[mid]){
                return left;//说明左边的最小
            }else {
                return mid;//说明中间的最小
            }
        }
    }

    private static void insertSortRange(int[] array, int left, int right) {
        for(int i = left + 1; i <= right; i++){
            int tmp = array[i];
            int j = i - 1;
            for (; j >= 0; j--) {
                if(array[j] > tmp){
                    array[j + 1] = array[j];

                }else {
                    array[j + 1] = tmp;
                    break;
                }
            }
            array[j + 1] = tmp;
        }
    }
    private static int partitionFastAndSlowPoint(int[] array, int left, int right){
        int pre = left;
        int cur = pre + 1;
        int tmp = array[left];
        while(cur <= right){
            if(array[cur] < tmp && array[++pre] != array[cur]){
                swap(array,cur,pre);
            }
        }
        swap(array,left,pre);
        return pre;
    }

不用递归的方式---用栈来实现

java 复制代码
public static void quickSortNotRecursion(int[] array){
        int left = 0;
        int right = array.length - 1;
        Stack<Integer> stack = new Stack<>();
        stack.push(left);
        stack.push(right);
        while (!stack.isEmpty()){
            right = stack.pop();
            left = stack.pop();
            int pivo = partitionHoare(array,left,right);
            if(pivo > left + 1) {
                stack.push(left);
                stack.push(pivo-1);
            }
            if(pivo < right-1) {  //4:00上课
                stack.push(pivo+1);
                stack.push(right);
            }
        }
        System.out.println("快速排序非递归");
    }

四、归并排序

4.1 归并排序

思路:先将数组拆分,然后一步一步归并排序,从而使每次排序的个数少,减少了排序的时间

java 复制代码
/**
     * 排序方式:归并排序
     * 时间复杂度: O(N * log2(N) )
     * 稳定性:稳定
     * @param array
     */
    public static void mergeSort(int[] array){
        partitionMergeSort(array,0,array.length - 1);
        System.out.println("归并排序");
    }

    private static void partitionMergeSort(int[] array, int left, int right) {
        if(left >= right){
            return;
        }
        int mid = (left + right) / 2;
        partitionMergeSort(array,left,mid);
        partitionMergeSort(array,mid + 1,right);//进行拆分

        merge(array,left,mid,right);//归并
    }

    private static void merge(int[] array, int left, int mid, int right) {
        int[] tmp = new int[right - left + 1];//新建一个数组来存放排序后的数字
        int k = 0;//记录tmp的下标
        int leftstart = left;
        int rightstart = mid + 1;//因为右半边的数组从mid+1开始
        while (leftstart <= mid && rightstart <= right){
            if(array[leftstart] <= array[rightstart]){
                tmp[k++] = array[leftstart++];
            }else {
                tmp[k++] = array[rightstart++];
            }
        }
        //判断两边数组谁还没有被比较完,没有比较完的插入tmp的后面
        while (leftstart <= mid){
            tmp[k++] = array[leftstart++];
        }
        while (rightstart <= right){
            tmp[k++] = array[rightstart++];
        }
        for (int i = 0; i < k; i++) {
            array[left + i] = tmp[i];//将排好序的tmp数组放入原本的array数组中,
            						//这里的i+left是确定在array数组中的位置,即left不是0时
        }

    }

归并排序非递归

java 复制代码
public static void mergeSortNotRecursion(int[] array){//类似分治,将数组按一块一块的排序最后再整个排序
        int gap = 1;
        while (gap < array.length){
            for (int i = 0; i < array.length; i += gap * 2) {
                int left = i;//i位置为起始位置
                int mid = i + gap - 1;
                if(mid >= array.length){
                    mid = array.length - 1;//不要出界
                }
                int right = mid + gap;
                if(right >= array.length){
                    right = array.length - 1;//不要出界
                }
                merge(array,left,mid,right);
            }
            gap *= 2;
        }
        System.out.println("归并排序非递归");
    }

最后,完整的代码奉上

java 复制代码
import java.util.Stack;

public class MySort {


    /**
     * 排序方式:直接插入排序
     * 时间复杂度:O(n^2),但当数据趋于有序时,比如有序数组,那么时间复杂度为O(n)
     * 稳定性:稳定
     * @param array
     */
    public static void insertSort(int[] array){
        for(int i = 1; i < array.length; i++){
            int tmp = array[i];
            int j = i - 1;
            for (; j >= 0; j--) {
                if(array[j] > tmp){
                    array[j + 1] = array[j];

                }else {
                    array[j + 1] = tmp;
                    break;
                }
            }
            //走到这有两种可能,一种是已经将tmp放到正确的位置了
            //一种是j到了-1的位置tmp是最小值,要将0位置的值改成tmp
            array[j + 1] = tmp;
        }
        System.out.println("直接插入排序");
    }

    /**
     * 排序方式:希尔排序
     * 时间复杂度:根据不同的gap时间复杂度不同,可以粗略理解为O(n^1.25)
     * 稳定性:不稳定
     * @param array
     */
    public static void shellSort(int[] array){
        int gap = array.length;
        while (gap > 1){
            gap = gap/3 +1;
            shellSortReal(array,gap);
        }
        System.out.println("希尔排序");

    }

    private static void shellSortReal(int[] array,int gap) {
        for (int i = gap; i < array.length; i++) {
            int tmp = array[i];
            int j = i - gap;
            for (; j >= 0; j -= gap) {
                if(array[j] > tmp){
                    array[j + gap] = array[j];

                }else {
                    array[j + gap] = tmp;
                    break;
                }
            }
            array[j + gap] = tmp;
        }
    }


    /**
     * 排序方式:直接选择排序
     * 时间复杂度:O(n^2)
     * 稳定性:不稳定
     * @param array
     */
    public static void selectSort(int[] array){
        int left = 0;
        int right = array.length - 1;
        while (left < right){
            int minIndex = left;
            int maxIndex = left;
            for (int i = left; i <= right; i++) {
                if(array[i] < array[minIndex]){
                    minIndex = i;
                }
                if(array[i] > array[maxIndex]){
                    maxIndex = i;
                }
            }
            swap(array,minIndex,left);
            if(maxIndex == left) {//预防出现最大值在left位置,然后left的最大值被换到了minIndex位置
                maxIndex = minIndex;
            }
            swap(array,maxIndex,right);
            left++;
            right--;
        }
        System.out.println("直接选择排序");

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

    /**
     * 排序方式:堆排序
     * 时间复杂度:O(N * log2(N))
     * 稳定性:不稳定
     * @param array
     */
    public static void heapSort(int[] array){
        createHeap(array);
        int end = array.length - 1;
        while (end >= 0){
            swap(array,end,0);
            siftDown(array,0,end);//确保顶为最大值
            end--;
        }
        System.out.println("堆排序");
    }

    private static void createHeap(int[] array) {
        for(int parent = (array.length - 2) / 2; parent >= 0; parent--){
            siftDown(array,parent,array.length);
        }
    }

    private static void siftDown(int[] array,int parent, int length) {
        int child = 2 * parent + 1;
        while (child < length){
            if(child + 1 < length && array[child] < array[child + 1]){
                child++;
            }
            if(array[child] > array[parent]){
                swap(array,child,parent);
                parent = child;
                child = 2 * parent + 1;
            }else {
                break;
            }
        }
    }

    /**
     * 排序方式:冒泡排序
     * 时间复杂度:O(n^2)
     * 稳定性:稳定
     * @param array
     */
    public static void bubbleSort(int[] array){
        for (int i = 1; i < array.length; i++) {//第几次比较
            boolean flag = true;
            for (int j = 0; j < array.length - i; j++) {
                if(array[j] > array[j+1]){
                    swap(array,j,j+1);
                    flag = false;
                }

            }
            if(flag){
                break;
            }
        }
        System.out.println("冒泡排序");

    }

    /**
     * 排序方式:快速排序
     * 时间复杂度:O(Nlog2(N))
     * 稳定性:不稳定
     * @param array
     */
    public static void quickSort(int[] array){
        int left = 0;
        int right = array.length - 1;
        quickSortTree(array,left,right);
        System.out.println("快速排序");
    }
    public static void quickSortNotRecursion(int[] array){
        int left = 0;
        int right = array.length - 1;
        Stack<Integer> stack = new Stack<>();
        stack.push(left);
        stack.push(right);
        while (!stack.isEmpty()){
            right = stack.pop();
            left = stack.pop();
            int pivo = partitionHoare(array,left,right);
            if(pivo > left + 1) {
                stack.push(left);
                stack.push(pivo-1);
            }
            if(pivo < right-1) {  //4:00上课
                stack.push(pivo+1);
                stack.push(right);
            }
        }
        System.out.println("快速排序非递归");
    }


    private static void quickSortTree(int[] array, int left, int right) {
        if(left >= right){
            return;
        }
        if(right - left + 1 <= 10){//此时说明这个数组很小,如果经历了很多此递归,也已经趋于有序,用直接插入排序可以更快些
            insertSortRange(array,left,right);
            return;
        }

        int midIndex = getMidIndex(array,left,right);//将中间的数,最左边的数和最右边的数比较一下,找到最小的给左边的位置,这样在后序的
                                                    //的交换中,可以更快的将数组排好,因为数组更加趋于整齐了。
        swap(array,left,midIndex);

        int pivo = partitionFastAndSlowPoint(array,left,right);
        quickSortTree(array,left,pivo - 1);
        quickSortTree(array,pivo + 1,right);
    }

    private static int getMidIndex(int[] array, int left, int right) {
        int mid = (right - left) / 2;
        if(array[left] < array[right]){//左边的小于右边
            if(array[right] < array[mid]){
                return right;//说明右边的最小
            }else {
                return mid;//说明中间的最小
            }
        }else {//右边的小于等于左边
            if(array[left] < array[mid]){
                return left;//说明左边的最小
            }else {
                return mid;//说明中间的最小
            }
        }
    }

    private static void insertSortRange(int[] array, int left, int right) {//在一定范围内的插入排序
        for(int i = left + 1; i <= right; i++){
            int tmp = array[i];
            int j = i - 1;
            for (; j >= 0; j--) {
                if(array[j] > tmp){
                    array[j + 1] = array[j];

                }else {
                    array[j + 1] = tmp;
                    break;
                }
            }
            array[j + 1] = tmp;
        }
    }
    private static int partitionFastAndSlowPoint(int[] array, int left, int right){
        int pre = left;
        int cur = pre + 1;
        int tmp = array[left];
        while(cur <= right){
            if(array[cur] < tmp && array[++pre] != array[cur]){
                swap(array,cur,pre);
            }
        }
        swap(array,left,pre);
        return pre;
    }
    private static int partitionPothole(int[] array, int left, int right) {
        int tmp = array[left];
        while (left < right){
            while (left < right && array[right] >= tmp){//一直往左走,直到遇到比tmp小的数
                right--;
            }
            array[left] = array[right];//将这个小的数放到左边去
            while (left < right && array[left] <= tmp){//一直往左走,直到遇到比tmp大的数
                left++;
            }
            array[right] = array[left];//将这个大的数放到右边去
        }
        array[left] = tmp;
        return left;
    }

    private static int partitionHoare(int[] array, int left, int right) {
        int tmp = array[left];
        int sleft = left;
        while (left < right){
            while (left < right && array[right] >= tmp){//一直往左走,直到遇到比tmp小的数
                right--;
            }
            while (left < right && array[left] <= tmp){//一直往左走,直到遇到比tmp大的数
                left++;
            }
            swap(array,left,right);
        }
        swap(array,sleft,left);
        return left;
    }

    /**
     * 排序方式:归并排序
     * 时间复杂度: O(N * log2(N) )
     * 稳定性:稳定
     * @param array
     */
    public static void mergeSort(int[] array){
        partitionMergeSort(array,0,array.length - 1);
        System.out.println("归并排序");
    }
    public static void mergeSortNotRecursion(int[] array){//类似分治,将数组按一块一块的排序最后再整个排序
        int gap = 1;
        while (gap < array.length){
            for (int i = 0; i < array.length; i += gap * 2) {
                int left = i;//i位置为起始位置
                int mid = i + gap - 1;
                if(mid >= array.length){
                    mid = array.length - 1;//不要出界
                }
                int right = mid + gap;
                if(right >= array.length){
                    right = array.length - 1;//不要出界
                }
                merge(array,left,mid,right);
            }
            gap *= 2;
        }
        System.out.println("归并排序非递归");
    }

    private static void partitionMergeSort(int[] array, int left, int right) {
        if(left >= right){
            return;
        }
        int mid = (left + right) / 2;
        partitionMergeSort(array,left,mid);
        partitionMergeSort(array,mid + 1,right);//进行拆分

        merge(array,left,mid,right);//归并
    }


    private static void merge(int[] array, int left, int mid, int right) {
        int[] tmp = new int[right - left + 1];//新建一个数组来存放排序后的数字
        int k = 0;//记录tmp的下标
        int leftstart = left;
        int rightstart = mid + 1;//因为右半边的数组从mid+1开始
        while (leftstart <= mid && rightstart <= right){
            if(array[leftstart] <= array[rightstart]){
                tmp[k++] = array[leftstart++];
            }else {
                tmp[k++] = array[rightstart++];
            }
        }
        //判断两边数组谁还没有被比较完,没有比较完的插入tmp的后面
        while (leftstart <= mid){
            tmp[k++] = array[leftstart++];
        }
        while (rightstart <= right){
            tmp[k++] = array[rightstart++];
        }
        for (int i = 0; i < k; i++) {
            array[left + i] = tmp[i];//将排好序的tmp数组放入原本的array数组中,这里的i+left是确定在array数组中的位置,即left不是0时
        }

    }


}

五、有关各个排序的复杂度

图片来源

总结

本篇文章主要介绍了七种比较常见的排序方式,包括插入、希尔、选择、堆、冒泡、快速、归并这几种,如果有什么不严谨不正确的地方,还望指正,谢谢大家!

相关推荐
埃菲尔铁塔_CV算法1 分钟前
FTT变换Matlab代码解释及应用场景
算法
music0ant2 分钟前
Idea 添加tomcat 并发布到tomcat
java·tomcat·intellij-idea
mashagua13 分钟前
RPA系列-uipath 学习笔记3
笔记·学习·rpa
计算机徐师兄31 分钟前
Java基于SSM框架的无中介租房系统小程序【附源码、文档】
java·微信小程序·小程序·无中介租房系统小程序·java无中介租房系统小程序·无中介租房微信小程序
源码哥_博纳软云32 分钟前
JAVA智慧养老养老护理帮忙代办陪诊陪护小程序APP源码
java·开发语言·微信小程序·小程序·微信公众平台
沐泽Mu35 分钟前
嵌入式学习-QT-Day05
开发语言·c++·qt·学习
许野平1 小时前
Rust: enum 和 i32 的区别和互换
python·算法·rust·enum·i32
chenziang11 小时前
leetcode hot100 合并区间
算法
chenziang11 小时前
leetcode hot100 对称二叉树
算法·leetcode·职场和发展
锦亦之22331 小时前
cesium入门学习二
学习·html