912排序數組

題目描述

給一個整數數組nums,將該數組升序排列。

提示

  • 1 <= nums.length <= 50000
  • 50000 <= nums[i] <= 5000

思路分析

力扣官方給大家提醒,要掌握各種排序方法。

  1. 冒泡。從左到右依次比較相鄰元素,前大於後則交換,每次冒泡保證最後一個元素是當前最大,再遍歷前 n-1 個元素。
  2. 選擇。找出前 n 個元素中max,與最後一個元素交換,再找前 n-1 個元素和第 n-1 個元素交換,以此類推。
  3. 插入。遍歷數組,保證當前元素左邊的數組有序,將當前元素插入對應位置。
  4. 歸併。分治思想,把數組劃分爲一個一個小塊,再分別排序,然後兩兩合併。合併時,需要用一個輔助數組存儲排序後的序列。
  5. 計數。當整數範圍不大時使用。創建一個長度爲max-min的數組,統計所有元素出現的次數,再根據次數把元素放回數組,實現排序。
  6. 桶排。把所有的元素放在一個一個的桶中(看成區間),把每個桶裏的元素排序,最後把桶中元素倒出就是排列好的數組。
  7. 快排。這裏避免發生極端情況,使用隨機快排。取最後一個元素 right 作爲分界點,把整個數組分爲兩塊/三塊,左邊的元素小於分界點,右邊的元素大於分界點,把分界點移到中間。再對左邊和右邊分別進行相同的操作。

代碼實現

    public int[] sortArray(int[] nums) {
        if (nums.length < 2) {
            return nums;
        }
        quickSort(nums, 0, nums.length - 1);
        bubbleSort(nums);
        selectSort(nums);
        insertSort(nums);
        mergeSort(nums, 0, nums.length - 1);
        bucketSort(nums);
        return nums;
    }

    //冒泡排序
    public void bubbleSort(int[] nums) {
        for (int i = nums.length - 1; i >= 1; i--) {
            for (int j = 1; j <= i; j++) {
                if (nums[j - 1] > nums[j]) {
                    swap(nums, j - 1, j);
                }
            }
        }
    }

    //選擇排序 每次找出n個元素的max放在最後的位置,之後n--
    public void selectSort(int[] nums) {
        for (int i = nums.length - 1; i >= 1; i--) {
            int max = 0;
            for (int j = 0; j <= i; j++) {
                max = nums[j] > nums[max] ? j : max;
            }
            swap(nums, i, max);
        }
    }

    //插入排序
    public void insertSort(int[] nums) {
        for (int i = 1; i < nums.length; i++) {
            int j = i;
            while (j > 0 && nums[j] > nums[j - 1]) {
                swap(nums, j, j - 1);
                j--;
            }
        }
    }

    //歸併排序
    public void mergeSort(int[] nums, int left, int right) {
        if (left >= right) {
            return;
        }
        int mid = left + (right - left) / 2;
        mergeSort(nums, left, mid);
        mergeSort(nums, mid + 1, right);
        merge(nums, left, right, mid);
    }

    public void merge(int[] nums, int left, int right, int mid) {
        int[] help = new int[right - left + 1];
        int p1 = left, p2 = mid + 1;
        int cur = 0;
        while (p1 <= mid && p2 <= right) {
            help[cur++] = nums[p1] <= nums[p2] ? nums[p1++] : nums[p2++];
        }
        while (p1 <= mid) {
            help[cur++] = nums[p1++];
        }
        while (p2 <= right) {
            help[cur++] = nums[p2++];
        }

        for (int i = 0; i < help.length; i++) {
            nums[left + i] = help[i];
        }
    }

    //計數排序
    public void countSort(int[] nums) {
        int min = Integer.MIN_VALUE;
        int max = Integer.MAX_VALUE;
        for (int num : nums) {
            min = Math.min(num, min);
            max = Math.max(num, max);
        }
        int[] count = new int[max - min + 1];
        for (int num : nums) {
            count[num - min]++;
        }
        int cur = 0;
        for (int i = 0; i < count.length; i++) {
            while (count[i] > 0) {
                nums[cur++] = i + min;
                count[i]--;
            }
        }
    }

    //桶排
    public void bucketSort(int[] nums) {
        //桶大小
        int size = 100;
        int min = Integer.MIN_VALUE;
        int max = Integer.MAX_VALUE;
        for (int num : nums) {
            min = Math.min(num, min);
            max = Math.max(num, max);
        }

        int count = max - min + 1;
        int bucketSize = count % size == 0 ? count / size : count / size + 1;
        List<Integer>[] buckets = new List[bucketSize];
        //將所有元素入桶
        for (int num : nums) {
            int quo = (num - min) / size;
            if (buckets[quo] == null) {
                buckets[quo] = new ArrayList<>();
            } else {
                buckets[quo].add(num);
            }
        }

        int cur = 0;
        for (List<Integer> bucket : buckets) {
            if (bucket != null) {
                bucket.sort(null);
                for (Integer integer : bucket) {
                    nums[cur++] = integer;
                }
            }
        }
    }

    //隨機快排
    public void quickSort(int[] nums, int left, int right) {
        if (left < right) {
            //隨機快排
            swap(nums, right, left + (int) (Math.random() * (right - left + 1)));

            int[] p = process(nums, left, right);
            quickSort(nums, left, p[0] - 1);
            quickSort(nums, p[1] + 1, right);
        }
    }

    public int[] process(int[] nums, int left, int right) {
        int less = left - 1;
        int more = right;
        while (left < more) {
            if (nums[left] < nums[right]) {
                swap(nums, left++, ++less);
            } else if (nums[left] > nums[right]) {
                swap(nums, left, --more);
            } else {
                left++;
            }
        }
        swap(nums, right, more);
        return new int[]{less + 1, more};
    }


    public void swap(int[] nums, int a, int b) {
        int tmp = nums[a];
        nums[a] = nums[b];
        nums[b] = tmp;
    }


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章