zoukankan      html  css  js  c++  java
  • 【基本排序重要思想】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 按照套路实现大顶堆
        }
    }
    
  • 相关阅读:
    史上最全最新java面试题合集二(附答案)
    史上最全最新Java面试题合集一(附答案)
    修改vsftpd的默认根目录/var/ftp/pub到其他目录
    重置密码解决MySQL for Linux错误:ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: YES)
    虚拟机下的Linux连接校园网上网问题
    CentOS7 安装Chrome
    CentOS7 卸载Firefox
    100个写作高级词
    【二叉搜索树】的详细实现(C++)
    【红黑树】的详细实现(C++)
  • 原文地址:https://www.cnblogs.com/HoweZhan/p/12604518.html
Copyright © 2011-2022 走看看