基数排序的介绍:
http://baike.baidu.com/view/1170573.htm
基数排序的方式可以采用LSD(Least significant digital)或MSD(Most significant digital),LSD的排序方式由键值的最右边开始,而MSD则相反,由键值的最左边开始。
以LSD为例,假设原来有一串数值如下所示: 73, 22, 93, 43, 55, 14, 28, 65, 39, 81 首先根据个位数的数值,在走访数值时将它们分配至编号0到9的桶子中: 0 1 81 2 22 3 73 93 43 4 14 5 55 65 6 7 8 28 9 39 接下来将这些桶子中的数值重新串接起来,成为以下的数列: 81, 22, 73, 93, 43, 14, 55, 65, 28, 39 接着再进行一次分配,这次是根据十位数来分配: 0 1 14 2 22 28 3 39 4 43 5 55 6 65 7 73 8 81 9 93 接下来将这些桶子中的数值重新串接起来,成为以下的数列: 14, 22, 28, 39, 43, 55, 65, 73, 81, 93 这时候整个数列已经排序完毕;如果排序的对象有三位数以上,则持续进行以上的动作直至最高位数为止。 LSD的基数排序适用于位数小的数列,如果位数多的话,使用MSD的效率会比较好。MSD的方式与LSD相反,是由高位数为基底开始进行分配,但在分配之后并不马上合并回一个数组中,而是在每个“桶子”中建立建立“子桶”,将每个桶子中的数值按照下一数位的值分配到“子桶”中。在进行完最低位数的分配后再合并回单一的数组中。
fafu1270:http://acm.fafu.edu.cn/problem.php?id=1270
这题 如果仅仅是过那很简单了,用queue直接排两次就能过,根本不用什么循环~~~ (不过不是老师的本意 - -#,管他呢,先过了再说 ……^_^)
// http://acm.fafu.edu.cn/problem.php?id=1270 #include <stdio.h> #include <queue> using namespace std; int num[30005]; int main(void) { queue<int> que[10]; int n; scanf("%d", &n); int val; int temp = n; int i; //刚读进来时就把数据按个位大小存到0~9队列中 while(temp--) { scanf("%d", &val); que[val%10].push(val); } //然后把队列中的数据首尾相连存到num数组中去 int index=0; for(i=0; i<10; i++) { while(!que[i].empty()) { num[index++] = que[i].front(); que[i].pop(); } } //最后按输入数据的十位再次存放到0~9队列中 for(i=0; i<n; i++) { que[num[i]/10%10].push(num[i]); } int foo=0; //然后把队列中的经过两次收集之后的数据打印出来 for(i=0; i<10; i++) { while(!que[i].empty()) { foo++; printf("%d%s", que[i].front(), foo%10==0 ? "\n": " "); que[i].pop(); } } return 0; }
// http://acm.fafu.edu.cn/problem.php?id=1270 #include <stdio.h> #include <queue> using namespace std; int num[30005]; queue<int> que[10]; void radix_sort(int * array, int radix, int n) { // radix是要排的位数, 比如说把一堆数按个位和十位排两次,那radix=2 // n是num数组中元素的个数 int j; int k=1; // k is an important variable, can't used by others for(int i=1; i<=radix; i++) //对radix扫描:个位,十位,百位…… { //把所有的数按某一位放入队列数组中 for(j=0; j<n; j++) que[array[j]/k%10].push(array[j]); k *= 10; //把所有数据首尾相连后再次放入数组中去 j = 0; for(int i=0; i<10; i++) //扫描队列数组 { while(!que[i].empty()) { array[j++] = que[i].front(); que[i].pop(); } } } } int main(void) { int n,i; scanf("%d", &n); //把数据读到数组中去 for(i=0; i<n; i++) scanf("%d", &num[i]); radix_sort(num, 2, i); //打印出排序后的数据 for(i=0; i<n; i++) printf("%d%s", num[i], (i+1)%10==0 ? "\n" : " "); return 0; }
版本三:
可以不用指定位数来进行排序了
#include <stdio.h> #include <queue> using namespace std; int num[30005]; queue<int> que[10]; void radix_sort(int * array, int length) { int j; int k=1; bool scan_over = false; while(true) //对radix扫描:个位,十位,百位…… { if(scan_over) break; scan_over = true; //把所有的数按某一位放入队列数组中 for(j=0; j<length; j++) { if(array[j]/k != 0) scan_over = false; que[array[j]/k%10].push(array[j]); } k *= 10; //把所有数据首尾相连后再次放入数组中去 j = 0; for(int i=0; i<10; i++) //扫描队列数组 { while(!que[i].empty()) { array[j++] = que[i].front(); que[i].pop(); } } if(!scan_over) printf("k is %d\n", k); } } int main(void) { int n,i; scanf("%d", &n); //把数据读到数组中去 for(i=0; i<n; i++) scanf("%d", &num[i]); radix_sort(num, i); //打印出排序后的数据 for(i=0; i<n; i++) printf("%4d%s", num[i], (i+1)%10==0 ? "\n" : " "); return 0; }