真題2017 問答題 計數排序
阿新 • • 發佈:2018-12-19
計數排序可以對0到k臨時陣列的n個整數進行排序,K為整數,排序的時間複雜度為O(n+k),它不是基於比較的演算法,時間複雜度低於任何基於比較的排序演算法。計數排序是穩定的排序。 基本思想:對每一個輸入元素x,輸入小於x的元素個數,利用這一資訊,可以直接把x放到它在輸出陣列B中的位置上。其中用來計數的陣列C的長度取決於待排序陣列A中資料的範圍(等於待排序陣列的最大值與最小值的差加上1)。 演算法的步驟如下: 1.找出待排序的陣列中最大和最小的元素 2.統計陣列中每個值為i的元素出現的次數,存入陣列C的第i項 3.對所有的計數累加(從C中的第一個元素開始,每一項和前一項相加) 4.反向填充目標陣列:將每個元素i放在新陣列的第C(i)項,每放一個元素就將C(i)減去1。 在計數排序演算法的程式碼中,假設輸入是一個初始陣列A[1…n],A.length=n, 還需要兩個陣列,臨時陣列:C[0…k]提供臨時儲存空間; 輸出陣列:B[1…n]存放排序的輸出, 《演算法導論》中給出了計數排序的演算法虛擬碼:
在這裡插入程式碼片 COUNT—SORT(A,B,k) let C[0..k] be a new array for i=0 to k C[i]=0 for j=1 to A.length C[A[j]]=C[A[j]]+1 //步驟2 for i=1 to k //步驟3 C[i]=C[i]+C[i-1] for j=A.length downto 1 //步驟4 B[C[A[j]]]=A[j] //A[j]為第j個元素對應的票數,存放在C[j]上。陣列B順序輸出 C[A[j]]=C[A[j]]-1 //C[j]每輸出一個長度就減1 計數排序的程式碼為(陣列待排序的數字在0到99之間): 1.#include<iostream> 2.usingnamespacestd; 3.#include<stdlib.h> 4.intmain() 5.{ 6.voidfsort(inta[],intb[],intn); 7.inta[10]={15,54,40,69,91,3,7,9,10,45}; 8.intb[100]; 9.inti; 10.fsort(a,b,10); 11.for(i=1;i<=10;i++) 12.cout<<b[i]<<endl; 13.system("pause"); 14.return0; 15.} 16. 17.voidfsort(inta[],intb[],intn)//計數排序 18.{ 19.intc[100]; 20.inti=0; 21.for(i=0;i<100;i++) 22.c[i]=0; 23.for(i=0;i<n;i++) 24.c[a[i]]++; 25.for(i=1;i<100;i++) 26.c[i]+=c[i-1];//C[i]存放的是小於或者等於i的元素的個數 27.for(i=n-1;i>=0;i--) 28.{ 29.b[c[a[i]]]=a[i];//將a[i]放到b中合適的位置 30.c[a[i]]--; 31.} 32.}
N個數有N!個可能的排列情況,也就是說基於比較的排序演算法的判定樹有N!個葉子結點,比較次數至少為log(N!)=O(NlogN)(斯特林公式)。 而非基於比較的排序,如計數排序,桶排序,和在此基礎上的基數排序,則可以突破O(NlogN)時間下限。