第三章:查詢與排序(下)----------- 3.19 計數排序

Curtis_發表於2019-03-10

計數排序 

一句話:用輔助的陣列對陣列中出現的數字計數,元素轉下標,下標轉元素。

假設所有元素均大於等於0,依次掃描原陣列,將元素值k記錄在輔助陣列的k位上。

依次掃描輔助陣列,如果為1,將其插入目標是陣列的空白位處。

問題:

-----重複元素

-----有負數

優點:快;(可以說是最快的排序演算法,沒有比較,直接對映)

缺點:資料範圍很大,比較稀疏,會導致輔助空間很大,也稀疏,造成空間的浪費。

#include<iostream>
using namespace std;

void countSort(int arr[],int length){
	int maxL=arr[0];
	//求原陣列元素中的最大值 
	for(int i=1;i<length;i++){
		maxL=max(maxL,arr[i]);
	} 
	
	int helper[maxL+1];
	//輔助陣列賦初值為0	
	for(int i=0;i<=maxL;i++){
		helper[i]=0;
	}
	//遍歷原陣列,元素轉下標,若出現,則對應位置元素+1
	for(int i=0;i<length;i++){
		helper[arr[i]]++;
	} 
	
	int current=0;//資料回填的位置
	for(int i=1;i<=maxL;i++){
		while(helper[i]>0){
			arr[current++]=i;  //下標轉元素
			helper[i]--; 
		}
	} 
}

int main(){
	int arr[]={6,2,5,8,2,1,9,5,6};
	int len= 9;
	
	countSort(arr,len);
	for(int i=0;i<len;i++){
		cout<<arr[i]<<" ";
	}
	return 0;
} 

時間複雜度:掃描一次source,掃描一次helper,複雜度為N+k;

空間複雜度:輔助空間k,k=maxOf(source);

非原址排序;

如果要優化一下空間,可用求minOf(source),helper的長度為max-min+1,這樣能短點;

計數有缺陷,資料較為密集或者範圍較小是,適用。

 結果:

NOTICE:

 計數排序,適用資料範圍小,且範圍已知。

相關文章