LeetCode刷题日记:912. 排序数组

给你一个整数数组 nums,请你将该数组升序排列。
示例 1:

输入:nums = [5,2,3,1]
输出:[1,2,3,5]

示例 2:

输入:nums = [5,1,1,2,0,0]
输出:[0,0,1,1,2,5]

提示:

1 <= nums.length <= 5 * 104
-5 * 104 <= nums[i] <= 5 * 104

方法1:快速排序

public int[] sortArray(int[] nums) {
       QuickSort(nums, 0, nums.length-1);
       return nums;
    }
    /**
     * 入口函数(递归方法),算法的调用从这里开始。
     */
    public void QuickSort(int[] arr, int startIndex, int endIndex) {
        if (startIndex >= endIndex) {
            return;
        }

        // 核心算法部分:双边指针(交换法)
        int pivotIndex = doublePointerSwap(arr, startIndex, endIndex);
        
        // 用分界值下标区分出左右区间,进行递归调用
        QuickSort(arr, startIndex, pivotIndex - 1);
        QuickSort(arr, pivotIndex + 1, endIndex);
    }

    /**
     * 双边指针(交换法)
     * 思路:
     * 记录分界值 pivot,创建左右指针(记录下标)。
     * (分界值选择方式有:首元素,随机选取,三数取中法)
     *
     * 首先从右向左找出比pivot小的数据,
     * 然后从左向右找出比pivot大的数据,
     * 左右指针数据交换,进入下次循环。
     *
     * 结束循环后将当前指针数据与分界值互换,
     * 返回当前指针下标(即分界值下标)
     */
    private static int doublePointerSwap(int[] arr, int startIndex, int endIndex) {
        int pivot = arr[startIndex];
        int leftPoint = startIndex;
        int rightPoint = endIndex;

        while (leftPoint < rightPoint) {
            // 从右向左找出比pivot小的数据
            while (leftPoint < rightPoint
                    && arr[rightPoint] > pivot) {
                rightPoint--;
            }
            // 从左向右找出比pivot大的数据
            while (leftPoint < rightPoint
                    && arr[leftPoint] <= pivot) {
                leftPoint++;
            }
            // 没有过界则交换
            if (leftPoint < rightPoint) {
                int temp = arr[leftPoint];
                arr[leftPoint] = arr[rightPoint];
                arr[rightPoint] = temp;
            }
        }
        // 最终将分界值与当前指针数据交换
        arr[startIndex] = arr[rightPoint];
        arr[rightPoint] = pivot;
        // 返回分界值所在下标
        return rightPoint;
    }

结果:
在这里插入图片描述

方法2:堆排序

 public void swap(int[] array, int i, int j){
        int temp = array[i];
        array[i] = array[j];
        array[j] = temp;
    }

    // 堆排序
    public void heapSort(int[] array){
        int len = array.length;
        for (int i = len/2-1; i >= 0 ; i--) {
            adjustHeap(array, i, len);
        }
        for (int i = len - 1; i >= 0 ; i--) {
            swap(array, i, 0);
            adjustHeap(array, 0, i);
        }

    }

    // 调整堆元素
    public void adjustHeap(int[] array, int i, int length){
        //先取出当前元素i
        int temp = array[i];
        //从i结点的左子结点开始,也就是2i+1处开始
        for(int k=i*2+1;k<length;k=k*2+1){
            //如果左子结点小于右子结点,k指向右子结点(k = i*2+1为左节点,k = i*2+1+1为右节点)
            if(k+1<length && array[k]<array[k+1]){
                k++;
            }
            //如果子节点大于父节点,将子节点值赋给父节点(不用进行交换,后续归位)
            if(array[k] > temp){
                array[i] = array[k];
                i = k;
            }else{
                break;
            }
        }
        //将temp值放到最终的位置
        array[i] = temp;
    }

结果:
在这里插入图片描述

方法3:归并排序

 public int[] mergeSort(int[] array, int left, int right){

        if(left == right){
            return new int[]{array[left]};
        }

        int mid = (right - left)/2 + left;
        int[] leftArray = mergeSort(array, left, mid);
        int[] rightArray = mergeSort(array, mid+1, right);
        int[] newArray = new int[leftArray.length + rightArray.length];

        int index = 0, i = 0, j = 0;
        while (i < leftArray.length && j < rightArray.length){
            newArray[index++] = leftArray[i] < rightArray[j] ? leftArray[i++] : rightArray[j++];
        }
        while (i < leftArray.length){
            newArray[index++] = leftArray[i++];
        }
        while (j < rightArray.length){
            newArray[index++] = rightArray[j++];
        }
        return newArray;
    }

结果:
在这里插入图片描述

方法4:计数排序

 public int findMax(int[] array){
        // 查找最大值
        int max = Integer.MIN_VALUE;
        for (int i = 0; i < array.length; i++) {
            max = Math.max(max, array[i]);
        }
        return max;
    }
    /**
     * 查找出最小值
     * @param array
     * @return
     */
    public int findMin(int[] array){
        // 查找最大值
        int min = Integer.MAX_VALUE;
        for (int i = 0; i < array.length; i++) {
            min = Math.min(min, array[i]);
        }
        return min;
    }
    // 计数排序
    public int[] countSort(int[] array){
        int max = findMax(array);
        int min = findMin(array);
        int[] result = new int[array.length];
        int temp = max - min + 1;
        int[] count = new int[temp];
        for (int i = 0; i < array.length; i++) {
            count[array[i] - min] += 1;
        }
        for (int i = 1; i < count.length; i++) {
            count[i] += count[i-1];
        }
        for (int i = array.length-1; i >= 0 ; --i) {
            result[--count[array[i]-min]] = array[i];
        }
        return result;
    }

结果:
在这里插入图片描述

方法5:希尔排序

 //希尔排序
     public int[] hillSort(int[] array){
        int length = array.length;
        int mid = length/2;
        while (mid > 0){
            for (int i = mid; i < length; i++) {
                int temp = array[i];
                int index = i-mid;
                while (index >= 0 && array[index] > temp){
                    array[index+mid] = array[index];
                    index -= mid;
                }
                array[index + mid] = temp;
            }
            mid /= 2;
        }
        return array;
    }

结果:
在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值