在線編程--小範圍排序

小範圍排序是指一個幾乎有序的數組,個別元素需要進行調整,但調整的幅度不超過k,k相對於整個數組很小。
思想:可以使用插入排序,時間複雜度不超過O(N*k)
最好方法是使用堆排序,建立一個k大小的堆,對數組依次進行排序。

題目:
已知一個幾乎有序的數組,幾乎有序是指,如果把數組排好順序的話,每個元素移動的距離可以不超過k,並且k相對於數組來說比較小。請選擇一個合適的排序算法針對這個數據進行排序。
給定一個int數組A,同時給定A的大小n和題意中的k,請返回排序後的數組。
測試樣例:
[2,1,4,3,6,5,8,7,10,9],10,2
返回:[1,2,3,4,5,6,7,8,9,10]

import java.util.*;

public class ScaleSort {
    public int[] sortElement(int[] A, int n, int k) {
        // write code here
        if (A == null || A.length < 1 || n < k) {
            return A;
        }
        int[] heap = getHeap(A, k); // 先建立一個k大小的小根堆
        for (int i = k; i < n; i++) {
            A[i - k] = heap[0]; // 將調整好的heap[0]轉入A數組內
            heap[0] = A[i]; // 將下一個元素放入heap數組中 進行調整
            heapify(heap, 0, k);
        }
        // 此時堆內還剩下一些元素 進行排序
        for (int i = n - k; i < n; i++) {
            A[i] = heap[0];
            swap(heap, 0, k - 1);
            heapify(heap, 0, --k);
        }
        return A;
    }
    // 初始化k大小的小根堆
    public static int[] getHeap(int[] A, int k) {
        int[] heap = new int[k];
        for (int i = 0; i < k; i++) {
            insertHeap(heap, A[i], i);
        }
        return heap;
    }

    // 插入值
    public static void insertHeap(int[] heap, int value, int i) {
        heap[i] = value;
        while (i != 0) {
            int parent = (i - 1) / 2;
            if (heap[parent] > heap[i]) {
                swap(heap, parent, i);
                i = parent;
            } else {
                break;
            }
        }
    }

    public static void swap(int[] arr, int index1, int index2) {
        int tmp = arr[index1];
        arr[index1] = arr[index2];
        arr[index2] = tmp;
    }

    /*
     * index 對下標爲index的元素進行調整 heapSize heap堆的大小 最後剩餘的堆需要輸出
     */
    public static void heapify(int[] heap, int index, int heapSize) {
        int left = index * 2 + 1;
        int right = index * 2 + 2;
        int min = index;
        while (left < heapSize) {
            if (heap[left] < heap[index]) {
                min = left;
            }
            if (right < heapSize && heap[right] < heap[min]) {
                min = right;
            }
            if (min != index) {
                swap(heap, min, index);
            } else {
                break;
            }
            index = min;
            left = index * 2 + 1;
            right = index * 2 + 2;
        }
    }
}
發佈了88 篇原創文章 · 獲贊 31 · 訪問量 22萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章