桶排序--计数排序与相邻两数求最大差值问题

首先桶排序中有计数排序和基数排序,这里先只讨论计数排序。

时间复杂度O(n),额外空间复杂度O(n),对数据状况有限制,所以在排序算法中应用的较少。

基本思想:求出最大值和最小值,然后定义最大值与最小值差值的大小数组。然后对应下标就是这个数减去最小值的数。最后遍历bucket数组,取出数字并赋值到原数组中完成排序。

void Countnum(int* &arr,int n)
{
    //获取最大值和最小值
    int Max=arr[0];
    int Min=arr[0];
    for(int i=1;i)
    {
        Max=max(arr[i],Max);
        Min=min(arr[i],Min);
    }
    if (Max == Min)
    {
        return;
    }
    //将数组装进最大值与最小值之间的桶里
        //总共(Max-Min+1)个桶
    int* bucket=(int *)malloc(sizeof(int )*(Max-Min+1));
    for(int i=0;i<(Max-Min+1);i++)
    {
        bucket[i]=0;
    }
        //按序扔进桶里
    for (int i = 0; i < n; ++i)
    {
        bucket[arr[i]-Min]++;
    }
    int index=0;
    for(int i=0;i<(Max-Min+1);i++)
    {
        while(bucket[i])
        {
            //printf("%d\n",bucket[i]);
            arr[index++]=i+Min;
            bucket[i]--;
        }
    }
}

下面看一个经典例题:

给定一个数组,求如果排序之后,相邻两数的最大差值,要求时间复杂度O(N),且要求不能用非基于比较的排序。

这里先利用桶排序当作对拍程序,因为题目要求不能基于非比较排序,很显然桶排序就是非比较排序。然后利用桶的思想,n个数字建立n+1个长度个桶。将最大的数字放入最后一个桶,将最小的数字放在第一个桶,这样一定会有一个桶是空的。这样做的目的是排除在一个桶中存在结果的可能,也就是说一个同种的任意两个数的差值不可能比两个桶中间隔一个空桶的差值大。每个桶只记录最大,最小和有没有数字进入三个变量,然后循环遍历所有桶,记录所有非空桶与前一个非空桶的差值最大就是结果。

int MaxGap(int* arr,int n)
{
    if(arr == NULL || n <= 1) return 0;
    int Max=arr[0];
    int Min=arr[0];
    for (int i = 0; i < n; ++i)
    {
        Max = max (Max , arr[i]);
        Min = min (Min , arr[i]);
    }

    bool* Hasnum =(bool *)malloc(sizeof(bool)*(n+1));
    int* Maxs =(int *)malloc(sizeof(int)*(n+1));
    int* Mins =(int *)malloc(sizeof(int)*(n+1));

    for (int i = 0; i < n+1; ++i)
    {
        Maxs[i]=0;
        Mins[i]=0;
        Hasnum[i]=false;
    }
    int bid;
    for (int i = 0; i < n; ++i)
    {
        bid=Bucket(arr[i],n,Min,Max);
        Maxs[bid] = Hasnum[bid] ? max(Maxs[bid] , arr[i]): arr[i];
        Mins[bid] = Hasnum[bid] ? min(Mins[bid] , arr[i]): arr[i];
        Hasnum[bid]=true;
    }

    int res=0;
    int lastMax=Maxs[0];

    for (int i = 1; i < n+1; ++i)
    {
        if (Hasnum [i])
        {
            res=max(res,Mins[i]-lastMax);
            lastMax = Maxs[i];
        }
    }
    return res;


}    
int Bucket(long num,long len,long Min,long Max)
{
    return (int)((num-Min)*len/(Max-Min));
}

 

你可能感兴趣的:(桶排序--计数排序与相邻两数求最大差值问题)