(1)背景
已知乙個幾乎有序的陣列,幾乎有序是指,如果把陣列排好順序的話,每個元素移動的距離可以不超過k,並且k相對於陣列來說比較小。請選擇乙個合適的排序演算法針對這個資料進行排序。
給定乙個int陣列a,同時給定a的大小n和題意中的k,請返回排序後的陣列。
(2)分析
(2.1)思路一
插入排序:
插入排序能夠做到很好效果,時間複雜度o(nk),空間複雜度o(1);
(2.2)思路二
最小堆:
從左往右排序,i位置上最終放的數一定在區間[i,i+k]上。
可以每次只對[i,i+k]區間的數進行排序,確定i位置上的資料,然後區間向右移動乙個位置。
重複以上操作直到確定所有位置上的資料。
那麼對於區間[i,i+k]上的資料該採用什麼方法來排序呢。
如果選擇插入排序,每次移動位置後需要o(k)來確定i上的元素;
實際上在移動位置後,補充乙個新的資料到原有區間時,完全可以採用二分查詢,因為原有區間已經有序,
這樣時間複雜度降低為o(logk)。
本題可以採用大小為k+1的堆來進行排序,時間複雜度為o(nlogk)。
選擇堆起始大小為k的最小堆,由題意可知a[0~k-1] k個元素一定存在整個陣列中最小的值,將a[0~k-1]資料建立最小堆;
摘除堆頂放到ai[i從0開始,i++]處,再將a[k]放到最小堆的堆頂,調整繼續建堆;
直到剩下最後k個元素,然後再每次彈出堆頂,堆的大小k--.
摘除堆頂,再新增乙個元素,堆調整其時間複雜度為lgn;
一共有n個資料,需要摘除新增n次;所以整體時間複雜度o(nlogk),空間複雜度o(k).
(3)實現
public class main ;
main m=new main();
int a = m.sortelement(b,15,3);
for(int i=0;i0;k--)
return b;
}public void buildminheap(int a,int heapsize)
}public void minheapify(int a,int heapsize,int i)}}
幾乎有序陣列排序
題目 已知乙個 幾乎有序 的陣列,幾乎有序是指,如果把陣列排好順序的話,每個元素移動的距離可以不超過k 並且k相對於陣列來說比較小。請選擇乙個合適的排序演算法針對這個資料進行排序。給定乙個int陣列a,同時給定a的大小n和題意中的k,請返回排序後的陣列。思路 對於該題目,插入排序能夠做到很好效果,時...
有序陣列的合併
includeusing namespace std define size 1024 1 如果可以申請輔助空間,那麼從前從後倒是沒什麼所謂吧,這就像是歸併的一次歸併了。void merge 1 int arr,int lenarr,int brr,int lenbrr while low1 len...
有序陣列的插入
習題1.9 有序陣列的插入 20 分 本題要求將任一給定元素插入從大到小排好序的陣列中合適的位置,以保持結果依然有序。函式介面定義 bool insert list l,elementtype x 其中list結構定義如下 typedef int position typedef struct ln...