1. 程式人生 > 其它 >排序 - 基數排序(C語言)

排序 - 基數排序(C語言)

時間複雜度:O(P(N+B))

空間複雜度:O(N+B)

穩定性:穩定

其他排序演算法都假定排序記錄只有一個關鍵字,基數排序討論待排序記錄有多個關鍵字的排序問題。

次位優先

/* 基數排序 - 次位優先 */
 
/* 假設元素最多有MaxDigit個關鍵字,基數全是同樣的Radix */
#define MaxDigit 4
#define Radix 10
 
/* 桶元素結點 */
typedef struct Node *PtrToNode;
struct Node {
    int key;
    PtrToNode next;
};
 
/* 桶頭結點 */
struct HeadNode {
    PtrToNode head, tail;
};
typedef 
struct HeadNode Bucket[Radix]; int GetDigit ( int X, int D ) { /* 預設次位D=1, 主位D<=MaxDigit */ int d, i; for (i=1; i<=D; i++) { d = X % Radix; X /= Radix; } return d; } void LSDRadixSort(ElementType A[], int N ) { /* 基數排序 - 次位優先 */ int D, Di, i; Bucket B; PtrToNode tmp, p, List
= NULL; for (i=0; i<Radix; i++) /* 初始化每個桶為空連結串列 */ B[i].head = B[i].tail = NULL; for (i=0; i<N; i++) { /* 將原始序列逆序存入初始連結串列List */ tmp = (PtrToNode)malloc(sizeof(struct Node)); tmp->key = A[i]; tmp->next = List; List = tmp; }
/* 下面開始排序 */ for (D=1; D<=MaxDigit; D++) { /* 對資料的每一位迴圈處理 */ /* 下面是分配的過程 */ p = List; while (p) { Di = GetDigit(p->key, D); /* 獲得當前元素的當前位數字 */ /* 從List中摘除 */ tmp = p; p = p->next; /* 插入B[Di]號桶尾 */ tmp->next = NULL; if (B[Di].head == NULL) B[Di].head = B[Di].tail = tmp; else { B[Di].tail->next = tmp; B[Di].tail = tmp; } } /* 下面是收集的過程 */ List = NULL; for (Di=Radix-1; Di>=0; Di--) { /* 將每個桶的元素順序收集入List */ if (B[Di].head) { /* 如果桶不為空 */ /* 整桶插入List表頭 */ B[Di].tail->next = List; List = B[Di].head; B[Di].head = B[Di].tail = NULL; /* 清空桶 */ } } } /* 將List倒入A[]並釋放空間 */ for (i=0; i<N; i++) { tmp = List; List = List->next; A[i] = tmp->key; free(tmp); } }

主位優先和次位優先