桶排序

桶排序

①简单介绍

    桶排序如果输入数据服从均匀分布,平均情况下它的时间代价为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值。

排序中用到了之前提到的高速排序算法,用来对每一个桶里面的数据进行排序,实际上将数据放入桶中的时候就已经进行了一次排序了,相当于按大类分好,再用快排排序小类。当然这里不仅限于用快排来进行辅助,选择排序什么的都能够用。

posted @ 2017-07-10 21:33  jzdwajue  阅读(150)  评论(0编辑  收藏  举报