已知乙個幾乎有序的陣列,幾乎有序是指,如果把陣列排好順序的話,每個元素移動的距離可以不超過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]
分析:<1>首先分析時間複雜度為o(n)的排序演算法,其中有計數排序、基數排序,但是考慮到該題是不基於比較的排序演算法的限制,不適用;<2>其次時間複雜度為o(n*n)的排序演算法:氣泡排序和選擇排序,這兩個排序演算法與陣列原始序列無關,插入排序,插入排序的過程與原始順序有關,每個元素移動距離不超過k,所以說對於本題來說,插入排序o(n*k)就可以實現排序;<3>其次再看看時間複雜度為o(n*logn)的排序演算法:快速排序,與陣列原始順序無關,其主要是隨機的選擇乙個數,然後以這個數對陣列進行劃分,劃分出來的兩個部分再次進行遞迴;歸併排序,與陣列原始順序無關,把所有組打散,然後小組合大組,大組繼續合併,直到為一組;<4>最後我們分析改進後的堆排序來實現本題,由於陣列移動位置不超過k,我們可以將陣列a[0]-a[k-1]選做乙個小根堆,然後進行堆排序,找出0-(k-1)中的最小值,並彈出,然後在將a[1]-a[k]進行最小值的彈出,依次進行堆排序,直到該陣列有序,由於每次進行堆排序的時間複雜度為logk,一共有n個數,所以說改進後的堆排序時間複雜度為o(n*logk).
實現**:
package 直通bat面試演算法題;
public
class
scalesort
//從陣列中取出前k個數組成小根堆
int heap = getkheap(a, k);
//對k個數進行小根堆堆排序
for (int i = k; i < n; i++)
//新增乙個數
for (int i = n - k; i < n; i++)
return a;
}public
int getkheap(int a, int k)
return heap;
}//建立小根堆
public
void heapinsert(int heap, int value, int
index) else }}
public
void heapify(int arr, int
index, int heapsize)
if (right < heapsize && arr[right] < arr[smallest])
if (smallest != index) else
index = smallest;
left = index * 2 + 1;
right = index * 2 + 2;}}
public
void swap(int arr, int index1, int index2)
}
小範圍排序
給定乙個int陣列a,同時給定a的大小n和題意中的k,請返回排序後的陣列。時間複雜度 o n 的.桶排序 由於陣列大小和區別無法確定,最好別用 時間複雜度 o nlogn 的 堆排序 已經每個元素最多移動k個距離,那麼最下的那個數移動到陣列第乙個位置距離最多為k,可以建立長度為k的小根堆,並且彈出堆...
小範圍排序(C )
關於演算法與資料結構的相關博文 二叉樹相關練習題 c 經典排序演算法的c 實現 與字串有關的一些典型問題的c 解法 一些可以用動態規劃 dp 演算法解決的問題 c 排列組合相關筆試面試題 c 與概率相關的演算法題c 解法 附證明過程 二分查詢的巧妙運用 c 位運算在演算法題中的使用 c 鍊錶相關練習...
小範圍排序 使用堆排序
已知乙個幾乎有序的陣列,幾乎有序是指,如果把陣列排好順序的話,每個元素移動的距離可以不超過k,並且k相對於陣列來說比較小。請選擇乙個合適的排序演算法針對這個資料進行排序。給定乙個int陣列a,同時給定a的大小n和題意中的k,請返回排序後的陣列。測試樣例 2,1,4,3,6,5,8,7,10,9 10...