參考鏈接:https://blog.csdn.net/qq_19446965/article/details/81517552
桶排序
- 首先求出最大值最小值,把此區間劃分爲k個區間(即k個桶),再分別對桶內元素進行排序,將桶內元素合併得到排序結果。
- 假設數據均勻分佈,每個桶內元素爲 n/k 個,並對桶內元素通過快排排序,每次排序複雜度爲O(n/k log(n/k)),總的時間複雜度爲O(n) + O(k)*O(n/k log(n/k))=O(n) + O(n log(n/k)),當k接近n時,複雜度可以認爲是 O(n)
- 桶排序的複雜度與建桶的效果緊密相連,常見的建桶思路爲將最大值最小值之間的區間平分,或桶的個數爲 2^n,10^n
- 分治思想
基數排序
- 非比較算法
- 將所有待排整數統一爲位數相同的整數(常見的爲非負整數,對代碼稍作修改,負整數也可通過基數排序進行排序)
- 從最低位或最高位開始一次進行穩定排序,完成之後整個序列即爲一個有序序列
計數排序
- 以空間換時間
- 遍歷數組統計每個數出現的次數,根據統計結果寫回數組
- 是一種特殊的桶排序,當桶的個數最大時,桶排序即爲計數排序
複雜度比較
//d爲k進制下最長的位數
代碼實現
代碼實現思路與:https://www.cs.usfca.edu/~galles/visualization/Algorithms.html
基本一致
//sort
#include<iostream>
#include<vector>
#include<math.h>
#include<algorithm>
using namespace std;
void bucketSort(vector<int> &arr){
//將min和max等分成n份
int low=999999999;
int high=-999999999;
for(int i=0;i<arr.size();i++){
low=min(low,arr[i]);
high=max(high,arr[i]);
}
int size=(high-low)/10+1; //一個桶的區間大小
vector<int> bucket[10];
for(int i=0;i<arr.size();i++){
int index=(arr[i]-low)/size;
bucket[index].push_back(arr[i]);
}
for(int i=0;i<10;i++){
int bsize=bucket[i].size();
sort(bucket[i].begin(),bucket[i].end());
}
int index=0;
for(int i=0;i<10;i++){
for(int j=0;j<bucket[i].size();j++){
arr[index]=bucket[i][j];
index++;
}
}
}
//基數排序
//從低位開始排序
void redixSort(vector<int> &arr){
int maxx=-999999999;
for(int i=0;i<arr.size();i++){
maxx=max(maxx,arr[i]); //獲取最大值
}
int exp=10;
while(maxx/exp!=0){
exp*=10; //獲取最大值的位數
}
vector<int> bucket[10];
int exp2=10;
while(exp2<=exp){
for(int i=0;i<arr.size();i++){
bucket[(arr[i]%exp2)/(exp2/10)].push_back(arr[i]); //放到對應的桶中
}
int index=0;
for(int i=0;i<10;i++){
for(int j=0;j<bucket[i].size();j++){
arr[index]=bucket[i][j];
index++;
}
bucket[i].clear(); //因爲桶是重複使用的,所以在一輪結束之後注意將桶清空
}
exp2*=10;
}
}
//考慮負數,從低位開始排序
//將桶的大小擴展到20個即可
void redixSortp(vector<int> &arr){
int maxx=-999999999;
for(int i=0;i<arr.size();i++){
maxx=max(maxx,arr[i]); //獲取最大值
}
int exp=10;
while(maxx/exp!=0){
exp*=10; //獲取最大值的位數
}
vector<int> bucket[20];
int exp2=10;
while(exp2<=exp){
for(int i=0;i<arr.size();i++){
bucket[(arr[i]%exp2)/(exp2/10)+10].push_back(arr[i]); //放到對應的桶中
}
int index=0;
for(int i=0;i<20;i++){
for(int j=0;j<bucket[i].size();j++){
arr[index]=bucket[i][j];
index++;
}
bucket[i].clear(); //因爲桶是重複使用的,所以在一輪結束之後注意將桶清空
}
exp2*=10;
}
}
void countSort(vector<int>& arr){
int maxx=-999999999;
int minn=999999999;
for(int i=0;i<arr.size();i++){
maxx=max(maxx,arr[i]);
minn=min(minn,arr[i]);
}
int size=maxx-minn+1;
int count[size]={0};
for(int i=0;i<arr.size();i++){
count[arr[i]-minn]++;
}
int index=0;
for(int i=0;i<size;i++){
for(int j=0;j<count[i];j++){
arr[index]=i+minn;
index++;
}
}
}
int main(){
int a[20]={45,95,23,78,21,2,5,0,-69,5,9,159,87,65,25,-56,56,56,57,100};
vector<int> arr(a,a+20);
// bucketSort(arr);
redixSortp(arr);
// countSort(arr);
for(int i=0;i<20;i++){
cout<<arr[i]<<" ";
}
}