桶排序
1、思想概念
桶排序(bucketsort)假设输入数据服从均匀分布,平均情况下它的时间代价为O(n)。计数排序假设输入数据都属于一个小区间内的整数,而桶排序则假设输入是由一个随机过程产生,该过程将元素均匀、独立地分布在[0,1)区间上。
桶排序将[0,1)区间划分为n个相同大小的子区间,或称为桶。然后,将n个输入数分别放到各个桶中。因为输入数据是均匀、独立地分布在[0,1)区间上,所以一般不会出现很多数落在同一个桶中的情况。为了得到输出结果,先对每个桶中的数进行排序,然后遍历每个桶,按照次序把各个桶中的元素列出来即可。
在桶排序中,假设输入是一个包含n个元素的数组A,且每个元素A[i]满足0≤A[i]<1。算法还需要一个临时数组B[0..n-1]来存放链表(即桶),并假设存在一种用于维护这些链表的机制。
BUCKET-SORT(A)
1 n=A.length
2 let B[0..n-1] be a new array
3 for i=0 to n-1
4 make B[i] an empty list
5 for i=1 to n
6 insert A[i] into list B[⌊nA[i]⌋]
7 for i=0 to n-1
8 sort list B[i] with insertion sort
9 concatenate the lists B[0],B[1],…B[n-1] together in order
2、具体实现
#include<iostream>
using namespace std;
typedef struct node{
int key;
struct node * next;
}KeyNode;
//打印数组
void printBucketSort(int *arr, int len)
{
for (int i = 0; i < len; i++)
{
cout << arr[i] << " ";
}
cout << endl;
}
//桶排序
void BucketSort(int keys[], int size, int bucket_size){
KeyNode **bucket_table = (KeyNode **)malloc(bucket_size*sizeof(KeyNode *));
for (int i = 0; i<bucket_size; i++){
bucket_table[i] = (KeyNode *)malloc(sizeof(KeyNode));
bucket_table[i]->key = 0; //记录当前桶中的数据量
bucket_table[i]->next = NULL;
}
for (int j = 0; j<size; j++){
KeyNode *node = (KeyNode *)malloc(sizeof(KeyNode));//sizeof(KeyNode)=8
node->key = keys[j];
node->next = NULL;
//映射函数计算桶号
int index = keys[j] / 10;
//初始化P成为桶中数据链表的头指针
KeyNode *p = bucket_table[index];
//该桶中还没有数据
if (p->key == 0){
bucket_table[index]->next = node;
(bucket_table[index]->key)++;
}
else{
//链表结构的插入排序
while (p->next != NULL&&p->next->key <= node->key)
p = p->next;
node->next = p->next;
p->next = node;
(bucket_table[index]->key)++;
}
}
//打印结果
cout << "After BucketSort:" << endl;
for (int b = 0; b<bucket_size; b++)
for (KeyNode *k = bucket_table[b]->next; k != NULL; k = k->next)
cout << k->key << " ";
cout << endl;
}
void main(){
int array[] = { 27, 21, 49, 38, 65, 97, 76, 13, 49, 59 };
int size = sizeof(array) / sizeof(int);//数组长度
//桶排序前
cout << "Before BucketSort:" << endl;
printBucketSort(array, size);
//桶排序
BucketSort(array, size, 10);
system("pause");
}