基数排序是通过“分配”和“收集”过程来实现排序
(1)假设有欲排数据序列如下所示:
73 22 93 43 55 14 28 65 39 81
首先根据个位数的数值,在遍历数据时将它们各自分配到编号0至9的桶(个位数值与桶号一一对应)中。
分配结果(逻辑想象)如下图所示:
分配结束后。接下来将所有桶中所盛数据按照桶号由小到大(桶中由顶至底)依次重新收集串起来,得到如下仍然无序的数据序列:
81 22 73 93 43 14 55 65 28 39
接着,再进行一次分配,这次根据十位数值来分配(原理同上),分配结果(逻辑想象)如下图所示:
分配结束后。接下来再将所有桶中所盛的数据(原理同上)依次重新收集串接起来,得到如下的数据序列:
14 22 28 39 43 55 65 73 81 93
观察可以看到,此时原无序数据序列已经排序完毕。如果排序的数据序列有三位数以上的数据,则重复进行以上的动作直至最高位数为止。
代码 (C语言实现)
1 #ifndef __SINGLY_LINKED_LIST_H__
2 #define __SINGLY_LINKED_LIST_H__
3
4 typedef int ElementType;
5 struct Node;
6 typedef struct Node* PtrToNode;
7 typedef PtrToNode List;
8 typedef PtrToNode Position;
9
10 struct Node
11 {
12 ElementType Val;
13 Position Next;
14 };
15 void CreateList(List*);
16 void DeleteList(List);
17 int IsEmpty(List);
18 int IsLast(Position, List);
19 Position Header(List);
20 Position First(List);
21 Position Advance(Position);
22 Position Find(ElementType, List);
23 ElementType GetAt(Position);
24 void MakeEmpty(List);
25 void Delete(ElementType, List);
26 void Insert(ElementType, Position, List);
27 void InsertFront(ElementType, List);
28 void InsertBack(ElementType, List);
29
30 #endif
31 void CreateList(List* L)
32 {
33 PtrToNode pHeader = (struct Node*)malloc(sizeof(struct Node));
34 pHeader->Next = NULL;
35 *L = pHeader;
36 }
37
38 void DeleteList(List L)
39 {
40 MakeEmpty(L);
41 free(L);
42 }
43
44 int IsEmpty(List L)
45 {
46 return L->Next == NULL;
47 }
48
49 int IsLast(Position P, List L)
50 {
51 return P->Next == NULL;
52 }
53
54 Position Header(List L)
55 {
56 return L;
57 }
58
59 Position First(List L)
60 {
61 return L->Next;
62 }
63
64 Position Advance(Position P)
65 {
66 return P->Next;
67 }
68
69 Position Find(ElementType X, List L)
70 {
71 Position p = L->Next;
72 while(p != NULL && p->Val != X)
73 {
74 p = p->Next;
75 }
76 return p;
77 }
78
79 ElementType GetAt(Position P)
80 {
81 return P->Val;
82 }
83
84 void MakeEmpty(List L)
85 {
86 Position p, tmp;
87 p = L->Next;
88 while(p != NULL)
89 {
90 tmp = p->Next;
91 free(p);
92 p = NULL;
93 p = tmp;
94 }
95 L->Next = NULL;
96 }
97
98 void Delete(ElementType X, List L)
99 {
100 Position p, tmp;
101 p = L;
102 while(p->Next != NULL && p->Next->Val != X)
103 {
104 p = p->Next;
105 }
106 if(!IsLast(p, L))
107 {
108 tmp = p->Next;
109 p->Next = tmp->Next;
110 free(tmp);
111 tmp = NULL;
112 // 错误示范:
113 //free(p->Next);
114 //p->Next = tmp->Next;
115 }
116 }
117
118 void Insert(ElementType X, Position P, List L)
119 {
120 PtrToNode pNode;
121 pNode = (struct Node*)malloc(sizeof(struct Node));
122 pNode->Val = X;
123 pNode->Next = P->Next;
124 P->Next = pNode;
125 }
126
127 void InsertFront(ElementType X, List L)
128 {
129 Position pos;
130 PtrToNode pNode;
131 pos = L;
132 pNode = (struct Node*)malloc(sizeof(struct Node));
133 pNode->Val = X;
134 pNode->Next = pos->Next;
135 pos->Next = pNode;
136 }
137
138 void InsertBack(ElementType X, List L)
139 {
140 Position pos;
141 PtrToNode pNode;
142 // move to tail
143 pos = L;
144 while(pos->Next != NULL)
145 pos = pos->Next;
146 pNode = (struct Node*)malloc(sizeof(struct Node));
147 pNode->Val = X;
148 pNode->Next = pos->Next;
149 pos->Next = pNode;
150 }
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include "SinglyLinkedList.h"
4
5 #define N 10 // 排序的数个数
6 #define B 10 // 桶数,即基数
7 #define P 3 // 位数
8
9 void RadixSort(int arr[]);
10 int GetDigit(int x, int y);
11 void PrintArray(int arr[], int size);
12
13 int main()
14 {
15 int i;
16 //int arr[N];
17 int arr[N] = {64, 8, 216, 512, 27, 729, 0, 1, 343, 125}; // 10, 3
18 //int arr[N] = {64, 8, 216, 512, 125, 729, 0, 729, 343, 125};
19 //int arr[N] = {12, 58, 37, 64, 52, 36, 99, 63, 18, 9, 20, 88, 47}; // 13, 2
20
21 printf("before sort: ");
22 PrintArray(arr, N);
23
24 RadixSort(arr);
25
26 printf("after sort: ");
27 PrintArray(arr, N);
28
29 system("PAUSE");
30 return 0;
31 }
32
33 void RadixSort(int arr[])
34 {
35 int i, j, k, digit;
36 Position pos;
37 List bucket[B];
38
39 // 创建桶
40 for(i=0; i<B; ++i)
41 CreateList(&bucket[i]); // 从低位到高位循环每一位数字
42 for(i=0; i<P; ++i)
43 {
44 // 将桶置空
45 for(j=0; j<B; ++j)
46 MakeEmpty(bucket[j]); // 根据当前位上的数字,将之放入对应桶中。并注意顺序(后进的放在后面)
47 for(j=0; j<N; ++j)
48 {
49 digit = GetDigit(arr[j], i);
50 InsertBack(arr[j], bucket[digit]);
51 }
52 k = 0;
53 // 将每趟排序后的结果存回arr
54 for(j=0; j<B; ++j)
55 {
56 pos = First(bucket[j]);
57 while(pos != NULL)
58 {
59 arr[k++] = pos->Val;
60 pos = pos->Next;
61 }
62 }
63 }
64
65 for(i=0; i<B; ++i)
66 DeleteList(bucket[i]);
67 }
68
69
70 // 取整数x的倒数第y位数字,y从0开始
71 int GetDigit(int x, int y)
72 {
73 int i, t = 1;
74 for(i=0; i<=y; ++i)
75 t *= 10;
76 return (x % t) / (t / 10);
77 }
78
79
80 void PrintArray(int arr[], int size)
81 {
82 int i;
83 for(i=0; i<size; ++i)
84 {
85 printf("%d ", arr[i]);
86 }
87 printf("
");
88 }