【基本排序重要思想】912. 排序数组

问题描述: 给你一个整数数组nums,将该数组升序排列。
**示例:**

使用API就没多大的意义了。

方法一: 快速排序的实现
注意: 快速排序的边界情况还是比较烦人的,注意分情况,而且最后交换的时候一定是和right这个位置交换。

import java.util.Arrays;

class Solution {
    public int[] sortArray(int[] nums) {
        quickSort(nums, 0, nums.length - 1);
        return nums;
    }

    public void quickSort(int[] nums, int start, int end) {
        if (start < end) {
            int k = partition(nums, start, end);
            quickSort(nums, start, k - 1);
            quickSort(nums, k + 1, end);
        }
    }

    public int partition(int[] nums, int start, int end) {
        int base = start;
        int left = start + 1;
        int right = end;
        while (left <= right) {//一定要注意取等号的地方
            while (left <= right && nums[left] <= nums[base]) {
                left++;
            }
            while (left <= right && nums[right] >=nums[base]) {
                right--;
            }
            if (left < right) {
                swap(nums, left, right);
            }
        }
        swap(nums, base, right);//不管什么情况,都是和right交换
        return right;
    }

    private void swap(int[] nums, int a, int b) {
        int t = nums[a];
        nums[a] = nums[b];
        nums[b] = t;
    }

    public static void main(String[] args) {
        int[] nums = {5, 3, 1, 2};
        System.out.println(Arrays.toString(new Solution().sortArray(nums)));
    }
}

方法二: 归并排序
重在合并算法的理解

import java.util.Arrays;

class Solution {
    public int[] sortArray(int[] nums) {
        mergeSort(nums, 0, nums.length - 1);
        return nums;
    }

    public void mergeSort(int[] nums, int start, int end) {
        if (start < end) {
            int mid = start + ((end - start) >> 1);
            mergeSort(nums, start, mid);
            mergeSort(nums, mid+1, end);
            merge(nums,start,mid,end);
        }
    }

    public void merge(int[] nums, int start, int mid, int end) {
        int left = start;
        int right = mid + 1;
        int current = start;
        int[] cArr = Arrays.copyOf(nums, nums.length);//因为会修改nums,所以需要一个拷贝
        while(left <= mid && right <= end ) {
            if(cArr[left] < cArr[right]) {
                nums[current] = cArr[left];
                left++;
                current++;
            }else{
                nums[current] = cArr[right];
                right++;
                current++;
            }
        }
        while(left <= mid) {//如果左边还没合并完,继续合并
            nums[current] = cArr[left];
            left++;
            current++;
        }
    }

    public static void main(String[] args) {
        int[] nums = {5, 3, 1, 2};
        System.out.println(Arrays.toString(new Solution().sortArray(nums)));
    }
}

方法三: 堆排序


import java.util.Arrays;

class Solution {
    public int[] sortArray(int[] nums) {
        minHeapSort(nums, 0, nums.length - 1);
        return nums;
    }

    private static void minHeapSort(int[] array, int start, int end) {
        minHeap(array);//数组堆化
        for (int i = array.length - 1; i >= 0; i--) {
            swap(array, 0, i);//每次都和堆顶和最后一个元素交换
            minHeapFixDown(array, 0, i - 1);//调整的范围要减小
        }
    }

    private static void minHeap(int[] array) {
        int n = array.length / 2 - 1;
        for (int i = n; i >= 0; i--) {
            minHeapFixDown(array, i, array.length - 1);
        }
    }

    private static void minHeapFixDown(int[] array, int root, int len) {
        //找到左右孩子节点
        int lChild = root * 2 + 1;
        int rChild = root * 2 + 2;
        //找到左右孩子比较小的那个,准备和根节点比较大小
        int min = lChild;
        if (lChild > len) {
            return;
        }
        if (rChild > len) {
            min = lChild;
        } else {
            if (array[lChild] > array[rChild]) {
                min = rChild;
            }
        }
        //和根节点比较,如果小的话,那么不用调整
        if (array[root] <= array[min]) {
            return;
        } else {
            //将根节点和较小的节点交换
            swap(array, min, root);
        }
        //递归
        minHeapFixDown(array, min, len);
    }

    private static void swap(int[] nums, int base, int right) {
        int t = nums[right];
        nums[right] = nums[base];
        nums[base] = t;
    }

    public static void main(String[] args) {
        int[] nums = {5, 3, 1, 2};
        System.out.println(Arrays.toString(new Solution().sortArray(nums))); //5,3,1,2 按照套路实现大顶堆
    }
}
posted @ 2020-03-31 13:11  bestwell  阅读(193)  评论(0编辑  收藏  举报