桶排序(8.3)

1.理论

桶排序的基本思想

       假设有一组长度为N的待排关键字序列K[1....n]。首先将这个序列划分成M个的子区间(桶) 。然后基于某种映射函数 ,将待排序列的关键字k映射到第i个桶中(即桶数组B的下标 i) ,那么该关键字k就作为B[i]中的元素(每个桶B[i]都是一组大小为N/M的序列)。接着对每个桶B[i]中的所有元素进行比较排序(可以使用快排)。然后依次枚举输出B[0]....B[M]中的全部内容即是一个有序序列。

桶—关键字映射函数

      bindex=f(key)   其中,bindex 为桶数组B的下标(即第bindex个桶), k为待排序列的关键字。桶排序之所以能够高效,其关键在于这个映射函数,它必须做到:如果关键字k1<k2,那么f(k1)<=f(k2)。也就是说B(i)中的最小数据都要大于B(i-1)中最大数据。很显然,映射函数的确定与数据本身的特点有很大的关系,我们下面举个例子:

 

假如待排序列K= {49、 3835、 9776、 7327、 49 }。这些数据全部在1—100之间。因此我们定制10个桶,然后确定映射函数f(k)=k/10。则第一个关键字49将定位到第4个桶中(49/10=4)。依次将所有关键字全部堆入桶中,并在每个非空的桶中进行快速排序后得到如下图所示:

                                                      

对上图只要顺序输出每个B[i]中的数据就可以得到有序序列了。

2.C代码

/*************************************************************************
	> File Name: bucketSort.c
	> Author: NULL
	> Mail: 574889524@qq.com
	> Created Time: 2014年11月02日 星期日 00时11分40秒
 ************************************************************************/

#include <stdio.h>
#include <stdlib.h>

#define ARRSIZE 8

struct node{
    int iKey;
    struct node *pNext;
};
/**********************************************/
void print(int *A,int length)    
{    
    int i;    
    for(i=0;i<length;++i)    
        printf("%d ",A[i]);    
    printf("\n");    
}    
/**********************************************/
void BucketSort(int *pArr,int iLenght,int iBucketSize)
{
    int i,j,index;
    struct node **pBucketTable = (struct node**)malloc(iBucketSize*sizeof(struct node));
    for(i=0;i<iBucketSize;++i){/*初始化桶*/
        pBucketTable[i]=(struct node*)malloc(sizeof(struct node));
        pBucketTable[i]->iKey  = 0;/*记录每一个桶中的元素个数*/
        pBucketTable[i]->pNext = NULL; 
    }

    for(i=0;i<iLenght;++i){
        struct node *pNode = (struct node *)malloc(sizeof(struct node));
        pNode->iKey  = pArr[i];
        pNode->pNext = NULL;
        
        index = pArr[i]/10;/*计算桶号*/
        struct node *pHead = pBucketTable[index];/*初始化pHead为桶中数据链表的头指针*/
        
        if(0 == pHead->iKey){/*说明桶中没有数据*/
            pBucketTable[index]->pNext = pNode;
            (pBucketTable[index]->iKey)++;
        }else{/*将数据插入到链表结构中*/
            while(pHead->pNext!=NULL && pHead->pNext->iKey <= pNode->iKey)
                pHead = pHead->pNext;
            pNode->pNext = pHead->pNext;
            pHead->pNext = pNode;
            (pBucketTable[index]->iKey)++;
        }
    }

    /*将结果返回*/
    i = 0;
    struct node *p,*q;
    for(j = 0;j<iBucketSize;j++)
        for(p=pBucketTable[j]->pNext;p!=NULL;p=p->pNext){
            pArr[i++] = p->iKey; 
        }
    /*释放内存*/
    for(j = 0;j<iBucketSize;j++){
        p=pBucketTable[j]->pNext;
        while(p!=NULL){
            q= p->pNext;
            free(p);
            p = q;
        }
        j++;
    }
    free(pBucketTable);
}
/**********************************************/

int main()
{
     int Arr[ARRSIZE]={49,38,65,97,76,13,27,49};     
    BucketSort(Arr,ARRSIZE,10);  
   print(Arr,ARRSIZE);
    return 0;
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

byd yes

你的鼓励是我最大的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值