0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
81 | 65 | 39 | |||||||
43 | 14 | 55 | 28 | ||||||
93 | |||||||||
22 | 73 |
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
28 | 39 | ||||||||
14 | 22 | 43 | 55 | 65 | 73 | 81 | 93 |
LSD的基數排序適用於位數小的數列,如果位數多的話,使用MSD的效率會比較好,MSD的方式恰與LSD相反,是由高位數為基底開始進行分配,其他的演算方式則都相同。
原文有作者自己写的各种语言的代码
这里我改写了下作者写的c代码
#include <string.h> #include <stdlib.h> #include <stdio.h> #include <math.h> #include <time.h> #include <vector> using namespace std; void swap(int &a,int&b) { int tmp = a; a = b; b = tmp; } void radix_sort(int *array,int number_of_data,int length) { int counter = 0; int n =1; while (counter<number_of_data) { int counter_for_index[10] = {0};//桶中的计数器 表示放了多少个元素 int tmp[10][10] = {0}; //将数据放入对应的桶中 for (int i = 0;i<length;i++) { int index = (array[i]/n)%10; tmp[index][counter_for_index[index]++] = array[i]; } n*=10; counter++;//位数计数器 //将放入桶中的数据写入原数组 int k = 0; for (int i= 0;i<10;i++) { for (int j = 0;j<counter_for_index[i];j++) { array[k++] = tmp[i][j]; } } } } void main() { int a[] = {111,2,9,67,3,5,6,6,7,8}; radix_sort(a,3,sizeof(a)/sizeof(int)); for (int i = 0;i<sizeof(a)/sizeof(int);i++) { printf("%d ",a[i]); } printf("\n"); getchar(); }
下面是用队列和向量实现的MSD
from http://angels1.0.blog.163.com/blog/static/8458050420099294956971/
采用MSD过程如下:
第一次: 所有元素按照百位排序
0 号:059
1 号:179
2 号:232
3 号:332 361
4 号:457 405
5 号:589
6 号:633 644
7 号:714
8 号:825
9 号:
形成序列: 059 179 232 332 361 457 405 589 633 644 714 825 (已经基本有序)
第二次:桶内元素按照十位排序
从上面的可以看出只有3号4号和6号需要继续进行排序:
3号桶中 4号桶中 6号桶中
0 号: 0 号: 405 0 号:
1 号: 1 号: 1 号:
2 号: 2 号: 2 号:
3 号:332 3 号: 3 号: 633
4 号: 4 号: 4 号:
5 号: 5 号:457 5 号:
6 号:361 6 号: 6 号: 644
7 号: 7 号: 7 号:
8 号: 8 号: 8 号:
9 号: 9 号: 9 号:
形成序列: 059 179 232 332 361 405 457 589 633 644 714 825 (其实已经有序了)
第三次:按照各位对各个桶元素排序:
由于各个桶内只剩下一个元素或没有元素,下面的就不再写了
#include <string.h> #include <stdlib.h> #include <stdio.h> #include <math.h> #include <time.h> #include <vector> #include <queue> using namespace std; //dem从0开始计算 获得num的第dem位 int getradix(int num,int dem) { while (dem--) { num/=10; } return (num % 10); } //dem表示数据的从0开始 如果是两位数 数据最多占据0 1 位置dem初始为1 void radix_sort(vector<int>&data,int dem ) { if (data.empty()||dem<0) { return ; } vector<queue<int>> buckets(10); //将元素放入桶中 for (int i = 0;i<data.size();i++) { int index = getradix(data[i],dem); buckets[index].push(data[i]); } //桶中的元素其实放在队列中存储的 所以先将队列中的元素放入向量中 for (int i = 0;i<10;i++) { //当元素个数大于1时 进行排序 if (buckets[i].size()>1) { vector<int> tmp; //将桶中的元素放入向量tmp中 while (!buckets[i].empty()) { tmp.push_back(buckets[i].front()); buckets[i].pop(); } //递归进行排序 按dem-1位排序 radix_sort(tmp,dem-1); //将排好序的元素放入对于的桶中 for (int j = 0;j<tmp.size();j++) { buckets[i].push(tmp[j]); } }// if num of elem in bucket is big than 1,sort }//for every bucket //将桶中排好序的元素写入原向量中 int data_index = 0; for (int i = 0;i<10;i++) { while (!buckets[i].empty()) { data[data_index++] = buckets[i].front(); buckets[i].pop(); } } } void main() { vector<int> a; srand(time(NULL)); for (int i = 0;i<600;i++) { a.push_back(rand()%100); } radix_sort(a,1); for (int i = 0;i<a.size();i++) { printf("%d ",a[i]); } printf("\n"); getchar(); }