数据结构基础(15) --基数排序
来源:互联网 发布:vs2017 工具链接mysql 编辑:程序博客网 时间:2024/05/22 08:00
实现多关键字排序通常有两种作法:
最低位优先法(LSD)
先对K[0]{基数的最低位}进行排序,并按 K(0) 的不同值将记录序列分成若干子序列之后,分别对 K[1] 进行排序,..., K[d-1]依次类推,直至最后对最次位关键字排序完成为止。
最高位优先法(MSD)
先对 K[d-1]{基数的最高位}进行排序,然后对 K[d-2]进行排序,依次类推,直至对最主位关键字 K[0] 排序完成为止。
百度百科对基数排序做了如下介绍:
基数排序(radix sort)是属于“分配式排序”(distribution sort),基数排序法又称“桶子法”(bucket sort),顾名思义,它是透过键值的部份资讯,将要排序的元素分配至某些“桶”中,藉以达到排序的作用,基数排序法是属于稳定性的排序,在某些时候,基数排序法的效率高于其它的稳定性排序法。
链式基数排序基本步骤如下
1.将待排序记录以数组存储[或者以指针相链,构成一个链表]
2.”分配”时,按当前”关键字位”所取值,将记录分配到不同的”链表/链队列”(即不同的桶或堆中)中,每条链表中记录的”关键字位”相同;
3.”收集”时,按当前关键字位取值从小到大(即将这n条链表(n的大小为基数的大小)按照编号, 依次将其中所有的元素取出)将各链表中的元素取出放入到原先的数组或链表中;
4.对每个关键字位均重复 2) 和 3) 两步n次。
如采用LSD对{179, 208, 306, 93, 859, 984, 55, 9, 271, 33}(构成一个链表或者是数组)进行基数排序:
[第一步:按个位排]
[第二步:按十位排]
[第三步:按百位排]
代码实现(以LSD为例):
- //寻找数组中最大数字的位数
- template <typename Type>
- unsigned int maxBits(Type *begin, Type *end)
- {
- unsigned int bits = 1;
- //standard作为基准, 如果array中的元素
- //大于standard, 则bits+1
- int standard = 10;
- for (Type *current = begin; current != end; ++current)
- {
- while (*current >= standard)
- {
- standard *= 10;
- ++ bits;
- }
- }
- return bits;
- }
- /**说明:
- begin:数组起始
- end:数组结尾
- radix:基数
- */
- #define DEBUG
- template <typename Type>
- void radixSort(Type *begin, Type *end, int radix)
- {
- //找到数组中最大数字的位数
- int bits = maxBits(begin, end);
- //基数为radix, 则需要radix个链表
- std::list<Type> lists[radix];
- // 需要循环bits次
- for (int d = 0, factor = 1; d < bits; ++d, factor*=10)
- {
- //分配...
- for (Type *current = begin; current != end; ++current)
- {
- //取出相应位置上的数 (比如个位是1)
- int number = ((*current)/factor)%10;
- //则需要将之放到(分配到)标号为1的链表中
- lists[number].push_back(*current);
- }
- //收集...
- Type *current = begin;
- //对radix个链表中的元素进行收集
- for (int i = 0; i < radix; ++i)
- {
- while (!lists[i].empty())
- {
- *current = lists[i].front();
- ++ current;
- lists[i].pop_front();
- }
- }
- #ifdef DEBUG
- //打印排序的中间结果
- for (current = begin; current != end; ++ current)
- {
- cout << *current << ' ';
- }
- cout << endl;
- #endif // DEBUG
- }
- }
- template <typename Type>
- void radixSort(Type *array, int arraySize, int radix)
- {
- return radixSort(array, array+arraySize, radix);
- }
时间复杂度分析:
设待排序列为n个记录,d个关键码,关键码的取值范围为radix,则进行链式基数排序的时间复杂度为O(d(n+radix)),其中,一趟分配时间复杂度为O(n),一趟收集时间复杂度为O(radix),共进行d趟分配和收集.
附-测试代码:
- int main()
- {
- int array[10];
- for (int i = 0; i < 10; ++i)
- {
- array[i] = rand()%1000;
- }
- for (int i = 0; i < 10; ++i)
- {
- cout << array[i] << ' ';
- }
- cout << endl;
- radixSort(array, 10, 10);
- for (int i = 0; i < 10; ++i)
- {
- cout << array[i] << ' ';
- }
- cout << endl;
- return 0;
- }
原文地址:http://blog.csdn.net/zjf280441589/article/details/42609453
- 数据结构基础(15) --基数排序
- 数据结构基础(15) --基数排序
- 数据结构基础(15) --基数排序
- 数据结构基础7.7:基数排序
- 数据结构-基数排序
- 一步一步复习数据结构和算法基础-LSD基数排序
- 基础数据结构算法_计数排序,基数排序,桶排序
- 数据结构 排序 基数排序
- 基数排序 C语言数据结构
- 数据结构-算法: 基数排序
- 【数据结构】基数排序的哈希表
- 数据结构课程设计----基数排序
- 数据结构_基数排序
- [数据结构与算法]基数排序
- [数据结构] 基数排序算法
- 数据结构系列之基数排序
- 数据结构 基数排序的实现
- 【数据结构】-归并排序,基数排序
- Tasks and Back Stack
- Android学习遇到的问题及总结
- flash芯片替换SAMSUNG K9K8G08U0E替换K9K8G08U0B
- mybatis3 增删改查
- phpwind和discuz
- 数据结构基础(15) --基数排序
- JS提交表单
- 用ul,li制作表格时,如何去掉左边的点
- Spring Web MVC 的HandlerMapping的使用之-------SimpleUrlHandlerMapping(有三种配法)
- 线程安全与并发安全探究(二)
- 圆角
- bzoj2066: [Poi2004]Gra
- Num 21 : HDOJ: 题目1272 : 小希的迷宫 ( 并查集问题 )
- 学习网站