桶排序
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"); }