第三章:查詢與排序(下)----------- 3.21基數排序
基數排序:
基數排序過程無須比較關鍵字,而是通過“分配”和“收集”過程來實現排序,它的時間複雜度可達到線性階:O(n)。(ps:kN)。對於十進位制數來說,每一位的數在[0,9]之中,d位的數,則有d列。基數排序首先按低位有效數字進行排,然後逐次向上一位進行排序,直到最高位排序結束。
約定: 待排數字中沒有0,沒有負數(有負數,做一次轉換全部變為正數即可)
演算法過程:
(1)、假設有欲排資料序列如下所示:
73 22 93 43 55 14 28 65 39 81。
首先根據個位數的數值,在遍歷資料時將它們各自分配到編號0至9的桶(個位數值與桶號一一對應)中。
分配結果(邏輯想象)如下圖所示:
分配結束後。接下來將所有桶中所盛資料按照桶號由小到大(桶中由頂至底)依次重新收集串起來,得到如下仍然無序的資料序列:
81 22 73 93 43 14 55 65 28 39
(2)、接著,再進行一次分配,這次根據十位數值來分配(原理同上),分配結果(邏輯想象)如下圖所示:
分配結束後。接下來再將所有桶中所盛的資料(原理同上)依次重新收集串接起來,得到如下的資料序列:
14 22 28 39 43 55 65 73 81 93。
(3)以此類推……
如果排序的資料序列有三位數以上的資料,則重複進行以上的動作直至最高位數為止。
程式碼:
#include<iostream>
#include<cmath>
#include<vector>
using namespace std;
/**********************************/
//函式宣告:
void sort(int arr[],int d,int length);
void putInBucket(int data,int digitOn);
int getDigitOn(int src,int d);
/**********************************/
/***********************************/
//全域性變數:
vector<int> bucket[10];
//將陣列arr,按d這個位來分配和收集
void sort(int arr[],int length){
int d=1;//入桶依據的位初始化為1
int maxn=arr[0];//陣列的最大值
for(int i=1;i<length;i++){
maxn=max(maxn,arr[i]);
}
int dNum=1; //最大值有多少位
while(maxn/10!=0){
dNum++;
maxn/=10;
}
while(d<=dNum){
//依據第二個引數入桶和出桶
sort(arr,d++,length);
}
}
// 過載的sort:將陣列arr, 按d這個位來分配和收集
void sort(int arr[],int d,int length){
//全部入桶
for(int i=0;i<length;i++){
putInBucket(arr[i],getDigitOn(arr[i],d));
}
//出桶
//每個桶中的元素依次壓入原陣列
int k=0;
for(int j=0;j<10;j++){
while(bucket[j].size()){
arr[k++]=bucket[j].front();
bucket[j].erase(bucket[j].begin()); //比較巧妙,移除第一個元素!
}
}
}
//得到十進位制數src的第d位:
int getDigitOn(int src,int d){
return src/(int)(pow(10,d-1))%10;
}
void putInBucket(int data,int digitOn){
switch(digitOn){
case 0:
bucket[0].push_back(data);
break;
case 1:
bucket[1].push_back(data);
break;
case 2:
bucket[2].push_back(data);
break;
case 3:
bucket[3].push_back(data);
break;
case 4:
bucket[4].push_back(data);
break;
case 5:
bucket[5].push_back(data);
break;
case 6:
bucket[6].push_back(data);
break;
case 7:
bucket[7].push_back(data);
break;
case 8:
bucket[8].push_back(data);
break;
case 9:
bucket[9].push_back(data);
break;
}
}
int main(){
int arr[]={18,13,17,26,29,38,31,69,51};
int len=9;
sort(arr,len);
//列印結果:
for(int i=0;i<len;i++){
cout<<arr[i]<<" ";
}
return 0;
}
得到十進位制數src的第d位(需背住):
//得到十進位制數src的第d位:
int getDigitOn(int src,int d){
return src/(int)(pow(10,d-1))%10;
}
執行結果:
小結:
計數排序: 適用於小範圍資料;
桶排序: 適用於均勻分配的資料。
相關文章
- 第三章:查詢與排序(下)----------- 3.19 計數排序排序
- 第三章:查詢與排序(下)----------- 3.20桶排序排序
- 第三章:查詢與排序(下)----------- 3.14 逆序對個數排序
- 第三章:查詢與排序(下)----------- 3.28 特殊排序(利用sort函式)排序函式
- 第三章:查詢與排序(下)----------- 3.16堆的概念及堆排序思路排序
- 第三章:查詢與排序(下)----------- 3.15基礎學習_樹、二叉樹、堆排序排序二叉樹
- 第三章:查詢與排序(下)----------- 3.27 用計數排序解決員工年齡問題排序
- 第三章:查詢與排序(下)----------- 3.22 總結:10種排序演算法的對比分析排序演算法
- 第三章:查詢與排序(下)----------- 3.23 相關題解:排序陣列中找和的因子排序陣列
- 第三章 :查詢與排序-------3.2你需要掌握的快速排序演算法排序演算法
- 第二章 :查詢與排序---------遞迴、查詢與排序補充排序遞迴
- 第三章:查詢與排序(下)----------- 3.12 實踐_最小可用id是多少排序
- 第三章 :查詢與排序-------3.7分治模式的完美詮釋_歸併排序排序模式
- 第二章 :查詢與排序-------希爾排序排序
- 第三章:查詢與排序(下)----------- 3.11 趣味擴充_尋找發帖水王排序
- 第三章:查詢與排序(下)----------- 3.9 最快效率求出亂序陣列中第k小的數排序陣列
- 排序和查詢排序
- 第三章:查詢與排序(下)----------- 3.29 題解:判斷陣列的包含問題排序陣列
- 第三章:查詢與排序(下)----------- 3.10 實戰解題_哪個數字超過了一半?排序
- 第三章:查詢與排序(下)------------- 3.8題解_調整陣列順序-奇數在左偶數在右排序陣列
- 第三章 :查詢與排序(下)-------3.1分治法介紹及關鍵點解析排序
- 【資料結構與演算法】非比較排序(計數排序、桶排序、基數排序)資料結構演算法排序
- 計數排序vs基數排序vs桶排序排序
- 桶排序和基數排序排序
- 第三章 :查詢與排序-------3.5快排之三指標分割槽法排序指標
- 第三章 :查詢與排序-------3.6快排在工程實踐中的優化排序優化
- 資料庫排序查詢資料庫排序
- 排序演算法__基數排序排序演算法
- 歸併排序和基數排序排序
- 第三章 :查詢與排序-------3.4快排之雙向掃描分割槽法排序
- 第二章 :查詢與排序-------遞迴形式進行插入排序排序遞迴
- 基於桶的排序之基數排序以及排序方法總結排序
- Django-ORM 之查詢排序DjangoORM排序
- java 基數排序Java排序
- 基於桶的排序之計數排序排序
- 第三章:查詢與排序(下)----------- 3.25 知其然知其所以然:小頂堆與topK的具體程式碼實現排序TopK
- Elasticsearch 按照標籤匹配個數優先排序查詢Elasticsearch排序
- 第二章 :查詢與排序-------二分查詢的遞迴解法排序遞迴