桶排序

/*
桶排序可用于最大最小值相差较大的数据情况,比如[9012,19702,39867,68957,83556,102456]。
但桶排序要求数据的分布必须均匀,否则可能导致数据都集中到一个桶中。
比如[104,150,123,132,20000], 这种数据会导致前4个数都集中到同一个桶中。导致桶排序失效。
	桶排序只要能恰当的恰到好处的实现桶的构造,可以大大优化性能
	关键在于桶的设计。而且桶其实数量需要自己估计的。
	下面来自网络的计数排序 基数排序 和桶排序的区别解释   这三种我们可以称桶式排序 
	If you are using bucket sort, you don't know how many buckets you will be using.
	 Whatever hash function you are using will determine the number of buckets.
	 If you are using counting sort, then you need a bucket for each unique value in the input
	  (actually you need a bucket for each value between 0 and max).
	If you are using radix sort and your numbers are decimal, then you need 10 buckets, 
	one for each digit from 0 to 9.
*/ 
/*
这里就存在两个问题:
(1)怎样划分数据块,也就是分几个桶,每个桶放哪几个数据。  用函数映射的方法来划分
(2)对每个数据块里的数据怎样排序	
	对每个数据块的元素进行排序即可,比如插入排序,快速排序等。
*/ 
#include <stdio.h>  
#include <stdlib.h>  
  
typedef struct node {  
    int key;  
    struct node *next;  
}KeyNode;  

void bucket_sort(int keys[],int size,int bucket_size) {  
    int i,j;
    KeyNode **bucket_table = (KeyNode **)malloc(bucket_size * sizeof(KeyNode*));  
	//二级指针的原因:一个数组元素代表一个链表  类似结构体数组 
    for(i = 0;i < bucket_size;i++) {  //给每一个指针数组分配头结点初始化 
        bucket_table[i] = (KeyNode*)malloc(sizeof(KeyNode));  
        bucket_table[i]->key = 0;
        bucket_table[i]->next = NULL;
    }
    for(j = 0;j < size;j++) { 	//把数据插进桶内   按照映射对应桶 
        KeyNode *node = (KeyNode *)malloc(sizeof(KeyNode));  //每有一个元素 创建一个节点 
        node->key = keys[j];  
        node->next = NULL;  
        int index = keys[j]/10;    //每个桶的映射为key/10  这个是类似hash算法的映射思想 
        //bucket-size = 10 也就是说数据最大为99 100/10 = 10 
        KeyNode *p = bucket_table[index];  	//指向index桶头结点的指针 
        if(p->key == 0) {  					//表示有0个元素 
            bucket_table[index]->next = node;  
            (bucket_table[index]->key)++;  
        }else {
            while(p->next != NULL && p->next->key <= node->key) //不止0个元素 则判断 key值大小 
                p = p->next;  									//找到插入的位置 
            node->next = p->next;  								//按照链表方式进行插入 
            p->next = node;  
            (bucket_table[index]->key)++;  						//头结点记录桶内的元素个数 
        } 
    }  
     //print(bucket_table);
	int h; //h用于遍历桶显示  
	for(h = 0;h < bucket_size;h++){
	//printf("第一次遍历后");
		KeyNode *temp = bucket_table[h]->next;			//指向头结点的next 
		if(0 != bucket_table[h]->key){		//头结点为0?:下一次循环:进入桶内 
	    	printf("第 %d 个桶内:",h+1);			
	    	while(NULL != temp->next){			
	    		printf("%d ",temp->key);		
				temp = temp->next;
			}
	    	printf("%d\n",temp->key);	
		}
	}
	printf("--------------------------\n");
    //print result  
    KeyNode * k = NULL;  
    for(i = 0;i < bucket_size;i++)  
        for(k = bucket_table[i]->next;k!=NULL;k=k->next)  
            printf("%d ",k->key);  
    printf("\n");  
	
}  
  
  
int main()  
{  
    int raw[] = {49,38,65,97,76,13,27,49};  
    int size = sizeof(raw)/sizeof(int);  
    bucket_sort(raw,size,10);  
}  

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值