基本有序陣列的排序 legend

2021-09-25 06:45:30 字數 1088 閱讀 5286

(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...