桶排序(Bucket Sort)
桶排序是另外一种以O(n)或者接近O(n)的复杂度排序的算法. 它假设输入的待排序元素是等可能的落在等间隔的值区间内.一个长度为N的数组使用桶排序, 需要长度为N的辅助数组. 等间隔的区间称为桶, 每个桶内落在该区间的元素. 桶排序是基数排序的一种归纳结果
算法的主要思想: 待排序数组A[1...n]内的元素是随机分布在[0,1)区间内的的浮点数.辅助排序数组B[0....n-1]的每一个元素都连接一个链表.将A内每个元素乘以N(数组规模)取底,并以此为索引插入(插入排序)数组B的对应位置的连表中. 最后将所有的链表依次连接起来就是排序结果.
这个过程可以简单的分步如下:
- 设置一个定量的数组当作空桶子。
- 寻访序列,并且把项目一个一个放到对应的桶子去。
- 对每个不是空的桶子进行排序。
- 从不是空的桶子里把项目再放回原来的序列中。
note: 待排序元素越均匀, 桶排序的效率越高. 均匀意味着每个桶在中间过程中容纳的元素个数都差不多,不会出现特别少或者特别多的情况, 这样在排序子程序进行桶内排序的过程中会达到最优效率.
note: 将元素通过恰当的映射关系将元素尽量等数量的分到各个桶(值区间)里面, 这个映射关系就是桶排序算法的关键.桶的标记(数组索引Index)的大小也要和值区间有对应关系。
以下是一段桶排序的源码:
1 #include <stdio.h> 2 3 void swap(int *a, int *b) 4 5 { 6 7 int temp = *a; 8 9 *a = *b; 10 11 *b = temp; 12 13 } 14 15 int partition(int *array, int low, int high) 16 17 { 18 19 int middle = (low + high)/2; 20 21 for(int i=low,j=high; i<j; ) { 22 23 while(array[i] < array[middle]) ++i; 24 25 if(i < j && i != middle) { 26 27 swap(&array[i], &array[middle]); 28 29 middle = i; 30 31 } 32 33 while(array[j] > array[middle]) --j; 34 35 if(i < j && j != middle) { 36 37 swap(&array[j], &array[middle]); 38 39 middle = j; 40 41 } 42 43 } 44 45 return middle; 46 47 } 48 49 int quicksort(int *array, int low, int high) 50 51 { 52 53 int piovt_pos; 54 55 if(low < high) { 56 57 piovt_pos = partition(array, low, high); 58 59 quicksort(array, low, piovt_pos - 1); 60 61 quicksort(array, piovt_pos + 1, high); 62 63 } 64 65 } 66 67 struct barrel { 68 69 int a[10]; 70 71 int count; 72 73 }; 74 75 int main() 76 77 { 78 79 int data[] = {23, 12, 3, 54, 1, 98, 24, 34}; 80 81 int min = data[0]; 82 83 int max = data[0]; 84 85 for(int i=1; i<sizeof(data)/sizeof(int); ++i) { 86 87 min = min < data[i] ? min : data[i]; 88 89 max = max > data[i] ? max : data[i]; 90 91 } 92 93 int num = (max - min + 1)/10 + 1; 94 95 barrel *pBarrel = new barrel[num]; 96 97 for(int i=0; i<sizeof(data)/sizeof(int); ++i) { 98 99 int j = (pBarrel+((data[i]-min+1)/10))->count; 100 101 (pBarrel+((data[i]-min+1)/10))->a[j] = data[i]; 102 103 (pBarrel+((data[i]-min+1)/10))->count++; 104 105 } 106 107 static int pos = 0; 108 109 for(int i=0; i<num; ++i) { 110 111 quicksort((pBarrel+i)->a, 0, (pBarrel+i)->count-1); 112 113 for(int j=0; j<(pBarrel+i)->count; ++j) { 114 115 data[pos++] = (pBarrel+i)->a[j]; 116 117 } 118 119 } 120 121 for(int i=0; i<8; ++i) { 122 123 printf("%d ", data[i]); 124 125 } 126 127 return 0; 128 129 }