排序算法四(桶排序)

一、桶排序算法的引入。

  之前我们已经说过了计数排序的算法。

  这个时候我们如果有这样的一个待排序数据序列:

int  x[14]={-10, 2, 3, 7, 20, 23, 25, 40, 41, 43,60, 80, 90, 100};

  我们如果按照计数排序的算法,那么待排序数据的范围是:-10 到 100

  我们为了实现对于这个数据集的遍历,这个时候需要额外的开辟一个大小为(100- (-10)+ 1)的空间,这个时候的空间复杂度达远远超过我们的预计,也就是这个造成了空间的浪费。

  所以我们可以说,计数排序还存在一个缺点:即数据里面的max 和min 的差值相比于待排序数据的数目来说,不能过大,否则会造成空间的浪费

  桶排序算法相当于做了一个对于计数排序算法做了一个升级。

  只不过计数排序算法计数是对于每一个排序数字进行的,而桶排序算法则将这个范围放宽,变成了一个范围。

二、桶排序算法的过程。

  1、比如对于上面的一个待排序数据,我们需要把它划分为一系列的范围,从min 到 min,这就相当于有了一个一个的“桶”。

  2、对应的范围的数据放入对应范围的桶里面。

  3、然后对于每一个范围的数据采用其他的排序算法进行排序,使得每一个桶内部的数据都是有序的,移动到已经有序的数据集中。

  上面有两个步骤比较关键:

  第一个是对于桶的范围的划分,这需要一个映射的规则,如果我们把桶划分的较小,这个时候几乎每一个数据都是一个桶;了,空间浪费。如果划分的太大,所有的数据都到了一个桶里面去,相当于没有划分。

  第二个是每一个桶的内部的排序算法的选择,这个影响最后总体的桶排序算法的稳定性。

三、例子

  对于上面的一个待排序数据,这个时候我们已经知道了max=100, min=-10.

  随后我们设计一个映射的规则,比如设计一个规则,使得 -10到 50 分为一个桶,50到100分为一个桶。

  我们可以设计这样的一个规则:

  ƒ(x)=x/30 - min/30

  这样我们就可以把上面的数组分成了四组:

根据结果分组 数据
0 -10, 2, 3, 7
1 20, 23 ,25 ,40, 41
2 60
3 80,  90, 100

  然后就可与根据分组分别进行排序。

四、算法

/*算法:桶排序C++版本*/
 
#include <iostream>
#include <vector>
#include <algorithm>
#include <math.h>
using namespace std;
 //这个算法的作用是对于数组A中位于位置A[l]到A[h]中的元素分为size个桶去排序
void bksort(float A[],int l,int h,int size){
    vector<float> b[size];//有size个数据,就分配size个桶
    int min=A[l];
    for(int i=l;i<=h;i++){//便利得到最小值
      if(A[i]<min)
           min=A[i];
    }
    for(int i=l;i<=h;i++){
        int bi = (A[i]-min)/size;//元素A[i]的桶编号,这里修改映射规则
        b[bi].push_back(A[i]);//将元素A[i]压入桶中
    }
    for(int i=0;i<size;i++)
        sort(b[i].begin(),b[i].end());//桶内排序
    int idx = l;//指向数组A的下标
    for(int i=0;i<size;i++){//遍历桶
        for(int j=0;j<b[i].size();j++){//遍历桶内元素
            A[idx++] = b[i][j];
        }
    }
}
 
int main(){
    float A[] = {0.78,0.17,0.39,0.26,0.72,0.94,0.21,0.12,0.23,0.68};
    bksort(A,2,9,3);
    for(int i=0;i<10;i++)
        cout<<A[i]<<" ";
}

五、复杂度分析

  复杂度主要是取决于排序算法。

  如果排序算法是快速排序,则可以达到Θ( n ) (大佬们的计算结果)

六、参考链接:

  复杂度计算看这个:https://blog.csdn.net/bqw18744018044/article/details/81738883

  算法的过程描述借鉴的是这个:https://www.jianshu.com/p/204ed43aec0c

  

猜你喜欢

转载自www.cnblogs.com/fantianliang/p/11881381.html