1,快速排序

快速排序原理是首先要找到一个中枢,把小于中枢的值放到他前面,大于中枢的值放到他的右边,然后再以此方法对这两部分数据分别进行快速排序。先看一下代码

    public int[] MySort(int[] arr) {
        quickSort(arr, 0, arr.length - 1);
        return arr;
    }

    private void quickSort(int[] array, int start, int end) {
        if (start < end) {
            int key = array[start];//用待排数组的第一个作为中枢
            int i = start;
            for (int j = start + 1; j <= end; j++) {
                if (key > array[j]) {
                    swap(array, j, ++i);
                }
            }
            array[start] = array[i];//先挪,然后再把中枢放到指定位置
            array[i] = key;
            quickSort(array, start, i - 1);
            quickSort(array, i + 1, end);
        }
    }

    //交换两个数的值
    public void swap(int[] A, int i, int j) {
        if (i != j) {
            A[i] ^= A[j];
            A[j] ^= A[i];
            A[i] ^= A[j];
        }
    }

这里是先用待排数组的第一个作为中枢,把数组划分两部分,小于他的往前挪,那大于他的自然就在后面了,然后再把中枢值放到大于和小于他之间的位置。
图片说明
快速排序其实有很多变种,这里就不在一一看了,想了解的可以看下《104,排序-快速排序》


2,归并排序

归并排序是把待排序序列分为若干个子序列,每个子序列是有序的。然后再把有序子序列合并为整体有序序列
图片说明
代码如下

    public int[] MySort(int[] arr) {
        int i = 1;
        while (i < arr.length) {
            //原理很简单,就是先两个两个合并,然后4个,然后8个……
            for (int j = 0; j + i < arr.length; j += 2 * i) {
                merge(arr, j, j + i - 1, Math.min(j + 2 * i - 1, arr.length - 1));
            }
            i = i << 1;
        }
        return arr;
    }

    private void merge(int[] data, int left, int center, int right) {
        int length = right - left + 1;
        int[] tmp = new int[length];
        int tempIndex = 0;
        //_left是前半部分开始的位置,_right是后半部分开始的位置
        int _left = left;
        int _right = center + 1;
        while (_left <= center && _right <= right) {
            if (data[_left] <= data[_right]) {
                tmp[tempIndex++] = data[_left++];
            } else {
                tmp[tempIndex++] = data[_right++];
            }
        }
        while (_right <= right) {
            tmp[tempIndex++] = data[_right++];
        }
        while (_left <= center) {
            tmp[tempIndex++] = data[_left++];
        }
        tempIndex = 0;
        while (tempIndex < length) {
            data[left + tempIndex] = tmp[tempIndex++];
        }
    }

3,堆排序

堆排序,也可以理解为二叉树排序,这里的堆分为两种,一种是大顶堆,一种是小顶堆,我们所有的排序方法都以升序为主,其实倒序原理也都差不多,所以这里我们主要分析的是大顶堆。大顶堆就是根节点不小于他的两个子节点,

图片说明

图片说明

代码如下

    public int[] MySort(int[] arr) {
        int length = arr.length;
        buildMaxHeap(arr, length);
        for (int i = 0; i < length; i++) {
            swap(arr, 0, length - 1 - i);
            maxHeapfy(arr, 0, length - i - 1);
        }
        return arr;
    }

    private void maxHeapfy(int[] arr, int i, int heapSize) {
        int left = i * 2 + 1;
        int right = i * 2 + 2;
        int largest = i;
        if (left < heapSize && arr[left] > arr[largest]) {
            largest = left;
        }
        if (right < heapSize && arr[right] > arr[largest]) {
            largest = right;
        }
        if (largest != i) {//把最大值给父节点
            swap(arr, largest, i);
            maxHeapfy(arr, largest, heapSize);
        }
    }

    private void buildMaxHeap(int[] array, int heapSize) {
        //从最后一个非叶子节点开始循环
        for (int i = (heapSize - 2) >> 1; i >= 0; i--) {
            maxHeapfy(array, i, heapSize);
        }
    }

    public void swap(int[] A, int i, int j) {
        if (i != j) {
            A[i] ^= A[j];
            A[j] ^= A[i];
            A[i] ^= A[j];
        }
    }

排序的方式太多了,这里就不在一一列举了,如果想了解更多,可以看下
《101,排序-冒泡排序》
《102,排序-选择排序》
《103,排序-插入排序》
《104,排序-快速排序》
《105,排序-归并排序》
《106,排序-堆排序》
《107,排序-桶排序》
《108,排序-基数排序》
《109,排序-希尔排序》
《110,排序-计数排序》
《111,排序-位图排序》
《112,排序-其他排序》


我把部分算法题整理成了PDF文档,截止目前总共有900多页,大家可以下载阅读
链接https://pan.baidu.com/s/1hjwK0ZeRxYGB8lIkbKuQgQ
提取码:6666

如果觉得有用就给个赞吧,还可以关注我的《牛客博客》查看更多的详细题解