桶排序

桶排序

①简介

    桶排序假设输入数据服从均匀分布,平均情况下它的时间代价为O(n)。桶排序假设输入是由一个随机过程产生,该过程将元素均匀,独立的分布在[0,1)区间上。

②原理

    桶排序将[0,1)区间划分为n个相同大小的子区间,或称为桶。然后将n个输入的数据分别放到各个桶中。因为输入数据是均匀分布的,一般不会出现很多数落在一个桶中的情况。为了得到输出结果,先对每个桶中的数据进行排序,再遍历每个桶,按照次序将元素取出。假设输入的是一个包含n个元素的数组A,并且每个元素A[i]满足0<=A[i]<1。此外,算法还需要一个临时数组B[0..n-1]来存放链表,也就是桶,并有一种用于维护这些链表的机制。也可以用数组来代替。
这里写图片描述

③C语言实现

#define BUCKET_NUM 10
#define BUCKET_SIZE 10

//快速排序,用来对每个桶中的数据进行排序
int partition(int* a, int start, int end)
{
    int x = a[end];
    int i = start;
    //调整整个数组中元素的位置并找出中间值的索引
    for (int j = start; j < end; j++)
    {
        if (a[j] <= x)
        {
            int t = a[i];
            a[i] = a[j];
            a[j] = t;
            i++;
        }
    }
    //将中间值放在找出的中间值索引处
    int t = a[i];
    a[i] = a[end];
    a[end] = t;
    return i;
}

//快速排序,用来对每个桶中的数据进行排序
void quick_sort(int* a, int from, int to)
{
    if (from < to)
    {
        int p = partition(a, from, to);
        quick_sort(a, from, p - 1);
        quick_sort(a, p + 1, to);
    }
}


//得到每个桶的当前索引
int get_bucket_index(int sub_bucket[])
{
    int index = 0;
    while (-1 != sub_bucket[index])
        index++;
    return index;
}

//将每个桶中数据挨个排序
void sort_sub_bucket(int bucket[BUCKET_NUM][BUCKET_SIZE])
{
    for (int i = 0; i < BUCKET_NUM; i++)
    {
        int to = get_bucket_index(bucket[i]);
        //对每个桶进行快速排序
        quick_sort(bucket[i],0,to - 1);
    }
}

//从桶中获取数据
void get_num(int* a, int bucket[BUCKET_NUM][BUCKET_SIZE])
{
    int array_index = 0;
    for (int i = 0; i < BUCKET_NUM; i++)
    {
        int to = get_bucket_index(bucket[i]);
        for (int j = 0; j < to; j++)
        {
            a[array_index++] = bucket[i][j];
        }
    }
}

void bucket_sort(int* a , int count)
{ 
    int bucket[BUCKET_NUM][BUCKET_SIZE];
    //初始化桶的数据
    for (int i = 0; i < BUCKET_NUM; i++)
    for (int j = 0; j < BUCKET_SIZE; j++)
        bucket[i][j] = -1;

    //将数据挨个放入桶中
    for (int i = 0; i < count; i++)
    {
        int digit = a[i] / 10;
        int bucket_index = get_bucket_index(bucket[digit]);
        bucket[digit][bucket_index] = a[i];
    }

    //将每个桶中的数据排个序
    sort_sub_bucket(bucket);

    //从桶中取出数据
    get_num(a,bucket);
}

void main()
{
    int count, *p;
    printf("请输入需要排序的数的个数 :");
    scanf_s("%d", &count);
    p = (int*)malloc(count * sizeof(int));
    printf("\n请输入需要排序的%d个数字:",count);
    for (int i = 0; i < count; i++)
    {
        scanf_s("%d", p+i);
    }
    printf("\n快速排序后的数组:");

    bucket_sort(p,count);

    for (int i = 0; i < count; i++)
    {
        printf("%d ", p[i]);
    }
    printf("\n");
    system("pause");
}

    在上面的桶排序中,一共有10个桶,每个桶的大小为10,因此只能比较100以内的数的大小,可以根据自己需要的范围来调整前面的define值。排序中用到了之前提到的快速排序算法,用来对每个桶里面的数据进行排序,实际上将数据放入桶中的时候就已经进行了一次排序了,相当于按大类分好,再用快排排序小类。当然这里不仅限于用快排来进行辅助,选择排序什么的都可以用。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值