若是咱們有N個整數,範圍從1到M(或從0到M-1)。咱們留置一個數組,稱之爲Count,大小爲M,並初始化爲零。因而,Count有M個單元(或桶),開始他們都是空的。當Ai被讀入時Count[Ai]增1。在全部輸入都被讀進以後,
掃描數組Count,打印輸出排好序的表。該算法花費O(M + N)。
多趟桶排序是基於這樣一個場景:在0到N^p-1間的N個數,p是某個常數,此時使用桶排序,那麼就會形成桶數量過多。因此,對於此種問題,採用最低(有效)位優先的多趟桶排序能夠得出正確的結果。
下面例子說明10個數的多趟桶排序的具體作法,本例輸入{64, 8, 216, 512, 27, 729, 0, 1, 343, 125}。html
+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+ | 0 | 1 | 512 | 343 | 64 | 125 | 216 | 27 | 8 | 29 | +-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+ | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | +-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+ 圖3-24 第一次排序 +-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+ | 8 | | 729 | | | | | | | | | 1 | 512 | 125 | | | | | | | | | 0 | 216 | 27 | | 343 | | 64 | | | | +-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+ | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | +-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+ 圖3-25 第二次排序 +-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+ | 64 | | | | | | | | | | | 27 | | | | | | | | | | | 8 | | | | | | | | | | | 1 | | | | | | | | | | | 0 | 125 | 216 | 343 | | 512 | | 729 | | | +-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+ | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | +-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+ 圖3-26 第三次排序
// 桶鏈表結構體 typedef struct Node{ // 存儲的數值 int Element; // 下一個桶指針 PtrToNode Next; } *PtrToNode; // [0-9]十個桶數組 PtrToNode Bucket[10];
struct Node; typedef struct Node *PrtToNode; typedef PrtToNode List; typedef PrtToNode Position; // 置空鏈表 List BMakeEmpty(List); //測試一個鏈表是否爲空 int BIsEmpty(List); // 在鏈表中查找第一個大於x的元素P Position BFind(int, List); // 刪除鏈表 void BDeleteList(List); // 在元素P後插入X void BInsertAfter(int, List, Position); // 輸出鏈表 void BPrint(List);
#include <stdio.h> #include <stdlib.h> #include "multi_bucket_sort.h" #define FatalError( Str ) fprintf( stderr, "%s\n", Str ), exit( 1 ) /** * 桶鏈表結構體 */ struct Node{ int Element; Position Next; }; /** * 置空鏈表 * @param L * @return */ List BMakeEmpty(List L) { if (L != NULL) { DeleteList(L); } L = malloc(sizeof(struct Node)); if (L == NULL) { FatalError("Out of memory!"); } L->Next= NULL; return L; } /** * 測試一個鏈表是否爲空 * @param L * @return */ int BIsEmpty(List L) { return L->Next == NULL; } /** * 在鏈表中查找第一個大於x的元素P * @param x * @param L * @return */ Position BFind(int x, List L) { Position P; P = L; while(P->Next != NULL && P->Next->Element <= x) { P = P->Next; } return P; } /** * 刪除鏈表 * @param L */ void BDeleteList(List L) { Position P, Tmp; P = L->Next; L->Next = NULL; while (P != NULL) { Tmp= P->Next; free(P); P = Tmp; } } /** * 在元素P後插入X * @param x * @param L * @param P */ void BInsertAfter(int x, List L, Position P) { if (P == NULL) { P = L; } Position TmpCell; TmpCell = malloc(sizeof(struct Node)); if (TmpCell == NULL) { FatalError("Out of space!"); } TmpCell->Element= x; TmpCell->Next = P->Next; P->Next = TmpCell; } /** * 輸出鏈表 * @param L */ void BPrint(List L) { Position P; P = L->Next; while (P != NULL) { printf("|%d|%x|", P->Element, P->Next); P = P->Next; if (P != NULL) { printf("-->"); } } printf("\n"); }
#include <stdio.h> #include <stdlib.h> #include <math.h> #include "ext/s13/multi_bucket_sort.h" int main(int argc, char** argv) { List Bucket[10], Current; int i, j, k, x; // 預排序數組 int a[10] = {64, 98, 21, 512, 23, 729, 30, 1, 343, 125}; // 三趟排序 for(i = 0; i < 3; i++) { // 鏈表置空 for (j = 0; j < 10; j++) { Bucket[j] = BMakeEmpty(NULL); } // 排序 for (k = 0; k < 10; k++) { x = a[k]; Current = Bucket[(int)(x/((int)pow(10, i)))%10]; // 插入排序 BInsertAfter(x, Current, BFind(x, Current)); } } // 結果輸出 for (j = 0; j < 10; j++) { if ( ! BIsEmpty(Bucket[j])) { BPrint(Bucket[j]); } } return (EXIT_SUCCESS); }