线性时间排序算法
线性时间排序算法包括:计数排序、桶排序、基数排序
计数排序
- 辅助的两个数组:一个用来计数,一个用来输出最后排序的数组
- 时间复杂度:O(n)
- 应用:n个输入元素中的每一个都是在0到k区间内的一个整数
- 计数排序是稳定排序,具有相同值得元素在输出数组中的相对次序与它们在输入数组中的相对次序相同
c++实现
void CountingSort(const vector<int> &arr, vector<int> &output, int k){
vector<int> temp(k,0);
for(int i=0;i<arr.size();i++)
temp[arr[i]]=temp[arr[i]]+1;
for(int i=1;i<=k;i++)
temp[i]=temp[i]+temp[i-1];
for(int j=arr.size();j>=0;j--){
output[temp[arr[j]]-1]=arr[j];
temp[arr[j]]=temp[arr[j]]-1;
}
}
基数排序
基于基数排序实现各个位的排序
- 时间复杂度:O(dN) d为最大数的位数
- 基数排序是稳定排序
c++实现
int getNuminPos(const int &num, int pos){
int temp=1;
for(int i=0;i<pos;i++)
temp*=10;
return (num/temp)%10;
}
void CountSort(vector<int> &arr, vector<int> &output, int pos){
vector<int> temp(10,0); int getPos=0;
for(int i=0;i<arr.size();i++){
getPos=getNuminPos(arr[i],pos);
temp[getPos]++;
}
for(int i=1;i<temp.size();i++)
temp[i]+=temp[i-1];
for(int j=arr.size()-1;j>=0;i--){
getPos=getNuminPos(arr[i],pos);
output[temp[getPos]-1]=arr[i];
temp[getPos]-=1;
}
}
int getMaxPos(int num){
if(num==0) return 0;
int pos=0;
while(num){
pos++;
num/=10;
}
return pos;
}
void RadixSort(vector<int> &arr){
vector<int> output(arr.size(),0);
int maxNum=*std::max_element(arr.begin().arr.end());
int pos=getMaxPos(maxNum);
for(int i=1;i<=pos;i++){
CountSort(arr, output, i);
arr=output;
}
}
桶排序
- 时间复杂度O(N)
c++实现
BucketSort(vector<double> &arr){
double minE=*std::min_element(arr.begin(),arr.end());
double maxE=*std::max_element(arr.begin(),arr.end());
int len=arr.size();
double interval=abs(max-min)/len;
vector<vector<double> > bucket;
for(int i=0;i<len;i++){
int pos=abs(arr[i]-minE)/interval;
bucket[pos].push_back(arr[i]);
}
for(int i=0;i<len;i++){
if(!bucket[i].empty())
std::sort(bucket[i].begin(),bucket[i].end());
}
int j=0;
for(int i=0;i<len;i++){
if(!bucket[i].empty())
for(int k=0;k<bucket[i].size();k++)
arr[j++]=bucket[i][k];
}
}