演算法 鴿巢排序

2021-09-27 08:59:39 字數 1671 閱讀 2727

鴿巢排序,名字很生動形象,其實就是把待排序的陣列中相同的元素扔到同乙個鴿巢。

洛谷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個點,則至少有兩個點在同乙個三角形中,這兩個...