桶排序思想

桶排序的思想就是把数组分到有限的桶中,然后再分别排序,最后将各个桶中的数据有序的合起来,具体如下:

(1)设计好桶的大小和桶的个数

(2)遍历数组,把每个元素放到对应的桶中

(3)对每个桶分别排序(可以递归使用桶排序,也可以使用其它排序)

(4)遍历桶中的数据,将数据有效的合起来

复杂度

桶排序利用函数映射关系,较少了几乎所有的比较操作。把大量数据分割成了基本有效的数据块,然后只需要对桶中的少量数据做先进的比较排序。

对 n 个关键字进行桶排序的时间复杂度分为两部分:

1、循环计算每个关键字的桶映射函数,这个时间复杂度是O(n).

2、利用比较先进的比较排序算法,对每个桶中的数据进行排序,其时间复杂度是∑ O(Ni*logNi) 。其中Ni 为第i个桶的数据量。

很显然,第(2)部分是桶排序性能好坏的决定因素。基于比较排序的最好平均时间复杂度只能达到O(N*logN),所以应该尽可能较少每个桶内数据的数量

映射函数f(k)能够将N个数据平均的分配到M个桶中,这样每个桶就有[N/M]个数据量。

所以尽量的增大桶的数量,极限情况下每个桶只能得到一个数据,这样就完全避开了桶内数据的“比较”排序操作。这就是一种空间换时间的策略。

总结

对于N个待排数据,M个桶,平均每个桶[N/M]个数据的桶排序平均时间复杂度为:

O(N)+O(M*(N/M)*log(N/M))=O(N+N*(logN-logM))=O(N+N*logN-N*logM)

当N=M时,即极限情况下每个桶只有一个数据时。桶排序的最好效率能够达到O(N)。

桶排序的平均时间复杂度为线性的O(N+C),其中C=N*(logN-logM).

空间复杂度O(N+M),如果输入数据非常庞大,而桶的数量也非常多,则空间代价无疑是昂贵的。

此外,桶排序是稳定的

代码实现

简易版


1 #include<stdio.h>  2 #include<algorithm>  3 #include<vector>  4 using namespace std;  5  6 const int bucket_num = 10;    //桶的数量  7 const int interval = 10;    //桶的容量  8 const int maxn = 100 + 10;        //数字的最大值  9 vector<int>buckets[bucket_num];    //每个桶 10  11 void BucketSort(int *arr, int n) 12 { 13     for (int i = 0; i < n; i++) 14         buckets[arr[i] / interval].push_back(arr[i]); 15     for (int i = 0; i < bucket_num; i++)  if (buckets[i].size()) 16         sort(buckets[i].begin(), buckets[i].end()); 17     for (int i = 0; i < bucket_num; i++)  if (buckets[i].size()) 18         for (int j = 0; j < buckets[i].size(); j++) 19             printf("%d ", buckets[i][j]); 20     printf("\n"); 21 } 22  23 int main() 24 { 25     int n, arr[maxn]; 26     printf("数组大小:"); 27     scanf("%d", &n); 28     printf("数组:"); 29     for (int i = 0; i < n; i++)  scanf("%d", &arr[i]); 30     BucketSort(arr, n); 31      32     return 0; 33 }


详细版


1 #include<stdio.h>   2 #include<stdlib.h>   3    4 const int  NARRAY = 50 + 5;  /* array size */   5 const int NBUCKET = 5; /* bucket size */   6 const int INTERVAL = 10; /* bucket range */   7    8 struct Node   9 {  10     int data;  11     struct Node *next;  12 };  13   14 void BucketSort(int arr[],int n);  15 struct Node *InsertionSort(struct Node *list);  16 void print(int arr[],int n);  17 void printBuckets(struct Node *list);  18 int getBucketIndex(int value);  19   20 void BucketSort(int arr[],int n)  21 {  22     struct Node **buckets;  23   24     /* allocate memory for array of pointers to the buckets */  25     buckets = (struct Node **)malloc(sizeof(struct Node*) * NBUCKET);  26   27     /* initialize pointers to the buckets */  28     for (int i = 0; i < NBUCKET; ++i) {  29         buckets[i] = NULL;  30     }  31   32     /* put items into the buckets,like insert from the head */  33     for (int i = 0; i < n; ++i) {  34         struct Node *current;  35         int pos = getBucketIndex(arr[i]);  36         current = (struct Node *) malloc(sizeof(struct Node));  37         current->data = arr[i];  38         current->next = buckets[pos];  39         buckets[pos] = current;  40     }  41   42     /* check what's in each bucket */  43     for (int i = 0; i < NBUCKET; i++) {  44         printf("Bucket[%d] : ", i);  45         printBuckets(buckets[i]);  46     }  47   48     /* sorting bucket using Insertion Sort */  49     for (int i = 0; i < NBUCKET; ++i) {  50         buckets[i] = InsertionSort(buckets[i]);  51     }  52   53     /* check what's in each bucket */  54       55     printf("-------------\n");  56     printf("Bucktets after sorted\n");  57   58     for (int i = 0; i < NBUCKET; i++) {  59         printf("Bucket[%d] : ", i);  60         printBuckets(buckets[i]);  61     }  62   63     /* put items back to original array */  64     for (int j = 0, i = 0; i < NBUCKET; ++i) {  65         struct Node *node;  66         node = buckets[i];  67         while (node) {  68             arr[j++] = node->data;  69             node = node->next;  70         }  71     }  72   73     /* free memory */  74     for (int i = 0; i < NBUCKET; ++i) {  75         struct Node *node;  76         node = buckets[i];  77         while (node) {  78             struct Node *tmp;  79             tmp = node;  80             node = node->next;  81             free(tmp);  82         }  83     }  84     free(buckets);  85     return;  86 }  87   88 /* Insertion Sort */  89 struct Node *InsertionSort(struct Node *list)  //list as head pionter  90 {  91     struct Node *k, *nodeList;  92     /* need at least two items to sort */  93     if (list == 0 || list->next == 0) {  94         return list;  95     }  96   97     nodeList = list;  98     k = list->next;  99     nodeList->next = 0; /* 1st node is new list */ 100     while (k != 0) { 101         struct Node *ptr; 102         /* check if insert before first */ 103         if (nodeList->data > k->data) { 104             struct Node *tmp;    //swap(k,nodeList) 105             tmp = k; 106             k = k->next; 107             tmp->next = nodeList; 108             nodeList = tmp; 109             continue; 110         } 111  112         for (ptr = nodeList; ptr->next != 0; ptr = ptr->next) { 113             if (ptr->next->data > k->data) break; 114         } 115  116         if (ptr->next != NULL) {  //if isn`t tail node,swap 117             struct Node *tmp; 118             tmp = k; 119             k = k->next; 120             tmp->next = ptr->next; 121             ptr->next = tmp; 122             continue; 123         } 124         else {                    //if isn tail node,insert at the tail 125             ptr->next = k; 126             k = k->next; 127             ptr->next->next = 0; 128             continue; 129         } 130     } 131     return nodeList; 132 } 133  134 int getBucketIndex(int value) 135 { 136     return value / INTERVAL; 137 } 138  139 void print(int arr[],int n) 140 { 141     for (int i = 0; i < n; ++i) { 142         printf("%3d",arr[i]); 143     } 144     printf("\n"); 145 } 146  147 void printBuckets(struct Node *list) 148 { 149     struct Node *cur = list; 150     while (cur) { 151         printf("%3d", cur->data); 152         cur = cur->next; 153     } 154     printf("\n"); 155 } 156  157 int main() 158 { 159     int n, array[NARRAY]; 160     printf("数组大小:"); 161     scanf("%d", &n);        //less than NBUCKET*INTERVAL 162     printf("数组:"); 163     for (int i = 0; i < n; i++)  scanf("%d", &array[i]); 164  165     printf("Initial array\n"); 166     print(array,n); 167     printf("-------------\n"); 168  169     BucketSort(array,n); 170     printf("-------------\n"); 171     printf("Sorted array\n"); 172     print(array,n); 173  174     return 0; 175 }