鴿巢排序,名字很生動形象,其實就是把待排序的陣列中相同的元素扔到同乙個鴿巢。
洛谷1177 排序
題目描述
將讀入的 n 個數從小到大排序後輸出。
輸入格式
第 1 行為乙個正整數 n。
第 2 行包含 n 個空格隔開的正整數 a[i],為你需要進行排序的數,資料保證了a[i]不超過10^9。
輸出格式
將給定的 n個數從小到大輸出,數之間用空格隔開。
輸入輸出樣例
輸入
542
451
輸出
124
45
說明提示
對於20% 的資料,有 n <= 10^3。
對於100% 的資料,有 n <=10^5 。
備註
本來洛谷1177是需要用快速排序來求解的,但實在找不到用鴿巢排序就能過的裸題,因此只好以這道題為例子了。這道題用鴿巢排序實際上只能拿60分,因為鴿巢排序對空間的需求量較大。
鴿巢排序,顧名思義就是把每乙個數當做乙個鴿巢,而乙個鴿巢記錄的就是a陣列中每個數出現的次數,這裡就用nest來記錄了,nest[i]表示i這個數在a陣列**現的次數,而根據a陣列計算得出這個nest陣列是極為簡單的。但考慮到負數情況,我們選擇對陣列進行平移,這裡我們取a陣列的最小值對應到0,既nest[i]表示(i + a_min)這個數在a陣列**現的次數。
最後再從a_min到a_max遍歷一遍,如果nest[i - a_min]大於0,就讓陣列a中從(當前有序數列的末位 + 1)到(當前有序數列的末位 + nest[i - a_min] + 1)的所有值等於i就好了,這樣就順利地將陣列a排好序了。
最後,算一下時間複雜度:這裡我們設m為最大值與最小值之差,那麼時間複雜度就是o(n + m)。這種排序演算法適合應用在n特別大,但m較小的情況。如果m太大,空間、時間都得炸。例如此題的前兩個測試點,就因為m太大,所以就re了。
# include
# include
# include
# include
# include
using
namespace std;
const
int n_max =
100000
, m_max =
100000000
;int n;
int a[n_max +10]
;int nest[m_max +10]
;void
pigeonsort()
for(
int i =
1; i <= n; i++
) nest[a[i]
- a_min]++;
int now =0;
for(
int i = a_min; i <= a_max; i++
)while
(nest[i - a_min]
--) a[
++now]
= i;
}int
main()
鴿巢排序 Pigeonhole sort
鴿巢排序,也被稱作基數分類,是一種 時間複雜度為 n 且在不可避免遍歷每乙個元素並且排序的情況下效率最好的一種 排序演算法.但它只有在差值 或者可被對映在差值 很小的範圍內的數值排序的情況下實用.當涉及到多個不相等的元素,且將這些元素放在同乙個 鴿巢 的時候,演算法的效率會有所降低.為了簡便和保持鴿...
鴿巢排序Pigeonhole sort
原理類似桶排序,同樣需要乙個很大的鴿巢 桶排序裡管這個叫桶,名字無所謂了 鴿巢其實就是陣列啦,陣列的索引位置就表示值,該索引位置的值表示出現次數,如果全部為1次或0次那就是桶排序 例如var pigeonhole new int 100 pigeonhole 0 的值表示0的出現次數.pigeonh...
鴿巢原理(初識)(純演算法)
一.什麼是 鴿巢原理 抽屜原理 若把n個物體放在n 1個抽屜中,至少有乙個抽屜中放了兩個物體。二.特點 只能用於解決存在性問題 三.例題 例一 在邊長為1的三角形放5個點,至少有兩個點之間的距離 1 2 解析 將乙個三角形分為4個三角形,在四個三角形中放5個點,則至少有兩個點在同乙個三角形中,這兩個...