Radix Sort
为了完成二维数据快速分类,最先使用的是hash分类。
前几天我突然想,既然基数排序的时间复杂度也不高,而且可能比hash分类更稳定,所以不妨试一下。
在实现上我依次实现:
1、一维数组基数排序
基本解决主要问题,涵盖排序,包含改进的存储分配策略。
如果用链表来实现,大量的函数调用将耗费太多时间。
2、二维数组基数排序
主要是实现和原有程序的集成。
一、数据结构
下面是存储节点的主数据结构。
- typedef struct tagPageList{
- int * PagePtr;
- struct tagPageList * next;
- }PageList;
- typedef struct tagBucket{
- int * currentPagePtr;
- int offset;
- PageList pl;
- PageList * currentPageListItem;
- }Bucket;
链表内是存储的一个4KB页面的指针。
每4KB页面可以存储最多1024个记录序号,如果是一维数组排序,那就直接存储数组元素了。
二、算法
基数排序可以分为MSD或者LSD。这里用的是LSD。
伪代码如下:
- for i= to sizeof(sorted-element-type){
- for each sorted-num{
- cell = sorted-num
- bucketIdx = (cell>>*i)&0xff
- bucket[bucketIdx] = cell
- }
- combine linked list nodes to overwrite original array
- }
C代码实现:
- int main(){
- HANDLE heap = NULL;
- Bucket bucket[BUCKETSLOTCOUNT];
- PageList * pageListPool;
- int plpAvailable = ;
- int * pages = NULL;
- int * pagesAvailable = NULL;
- int * objIdx;
- unsigned short * s;
- time_t timeBegin;
- time_t timeEnd;
- heap = HeapCreate(HEAP_NO_SERIALIZE|HEAP_GENERATE_EXCEPTIONS, *, );
- if (heap != NULL){
- pages = (int * )HeapAlloc(heap, , (TFSI/PAGEGRANULAR + BUCKETSLOTCOUNT + ) * );
- pageListPool = (PageList *)HeapAlloc(heap, , (TFSI/PAGEGRANULAR + ) * sizeof(PageList));
- s = (unsigned short *)HeapAlloc(heap, , TFSI*sizeof(unsigned short));
- objIdx = (int *)HeapAlloc(heap, , TFSI * sizeof(int));
- }
- MakeSure(pages != NULL && pageListPool != NULL && objIdx != NULL);
- for(int i=; i<TFSI; i++) objIdx[i]=i;
- timeBegin = clock();
- for (int i=; i<TFSI; i++) s[i] = rand();
- timeEnd = clock();
- printf("\n%f(s) consumed in generating numbers", (double)(timeEnd-timeBegin)/CLOCKS_PER_SEC);
- timeBegin = clock();
- for (int t=; t<sizeof(short); t++){
- FillMemory(pages, (TFSI/PAGEGRANULAR + BUCKETSLOTCOUNT + ) * , 0xff);
- SecureZeroMemory(pageListPool, (TFSI/PAGEGRANULAR + ) * sizeof(PageList));
- pagesAvailable = pages;
- plpAvailable = ;
- for(int i=; i<; i++){
- bucket[i].currentPagePtr = pagesAvailable;
- bucket[i].offset = ;
- bucket[i].pl.PagePtr = pagesAvailable;
- bucket[i].pl.next = NULL;
- pagesAvailable += PAGEGRANULAR;
- bucket[i].currentPageListItem = &(bucket[i].pl);
- }
- int bucketIdx;
- for (int i=; i<TFSI; i++){
- bucketIdx = (s[objIdx[i]]>>t*)&0xff;
- MakeSure(bucketIdx < );
- //save(bucketIdx, objIdx[i]);
- bucket[bucketIdx].currentPagePtr[ bucket[bucketIdx].offset ] = objIdx[i];
- bucket[bucketIdx].offset++;
- if (bucket[bucketIdx].offset == PAGEGRANULAR){
- bucket[bucketIdx].currentPageListItem->next = &pageListPool[plpAvailable];
- plpAvailable++;
- MakeSure(plpAvailable < TFSI/PAGEGRANULAR + );
- bucket[bucketIdx].currentPageListItem->next->PagePtr = pagesAvailable;
- bucket[bucketIdx].currentPageListItem->next->next = NULL;
- bucket[bucketIdx].currentPagePtr = pagesAvailable;
- bucket[bucketIdx].offset = ;
- pagesAvailable += PAGEGRANULAR;
- MakeSure(pagesAvailable < pages+(TFSI/PAGEGRANULAR + BUCKETSLOTCOUNT + ) * );
- bucket[bucketIdx].currentPageListItem = bucket[bucketIdx].currentPageListItem->next;
- }
- }
- //update objIdx index
- int start = ;
- for (int i=; i<; i++){
- PageList * p;
- p = &(bucket[i].pl);
- while (p){
- for (int t=; t<PAGEGRANULAR; t++){
- int idx = p->PagePtr[t];
- if (idx != TERMINATOR){
- objIdx[start] = idx;
- start++;
- }
- if (idx == TERMINATOR) break;
- }
- p = p->next;
- }
- }
- }
- timeEnd = clock();
- printf("\n%f(s) consumed in generating results", (double)(timeEnd-timeBegin)/CLOCKS_PER_SEC);
- //for (int i=0; i<TFSI; i++) printf("%d\n", s[objIdx[i]]);
- HeapFree(heap, , pages);
- HeapFree(heap, , pageListPool);
- HeapFree(heap, , s);
- HeapFree(heap, , objIdx);
- HeapDestroy(heap);
- return ;
- }
三、测试结果。
i7 3632QM @2.2GHz ==>TB 3.2GHz/ 8G RAM/ win8 64bit/VS2012 win32 release
1024*1024*100,1亿个随机生成 short 型数据。
1.438000(s) consumed in generating random numbers
4.563000(s) consumed in radix sort
12.719000(s) consumed in qsort
7.641000(s) consumed in std::sort
1024*1024*5 500万随机生成 short 型数据。
0.078000(s) consumed in generating random numbers
0.172000(s) consumed in radix sort
0.656000(s) consumed in qsort
0.390000(s) consumed in std::sort
1024*500
0.000000(s) consumed in generating random numbers
0.015000(s) consumed in radix sort
0.063000(s) consumed in qsort
0.047000(s) consumed in std::sort
四、讨论
二维数据分类上,性能相当于hash分类 约 1/3 。
比库例程稍快,慢的主要原因还是存储器,如果只是解决一维数组的话,调整下可以更快。
但对于二维数组多个线程同时操作,排序是不可接受的。
Radix Sort的更多相关文章
- 基数排序(radix sort)
#include<iostream> #include<ctime> #include <stdio.h> #include<cstring> #inc ...
- 经典排序算法 - 基数排序Radix sort
经典排序算法 - 基数排序Radix sort 原理类似桶排序,这里总是须要10个桶,多次使用 首先以个位数的值进行装桶,即个位数为1则放入1号桶,为9则放入9号桶,临时忽视十位数 比如 待排序数组[ ...
- [Algorithms] Radix Sort
Radix sort is another linear time sorting algorithm. It sorts (using another sorting subroutine) the ...
- 排序算法七:基数排序(Radix sort)
上一篇提到了计数排序,它在输入序列元素的取值范围较小时,表现不俗.但是,现实生活中不总是满足这个条件,比如最大整形数据可以达到231-1,这样就存在2个问题: 1)因为m的值很大,不再满足m=O(n) ...
- [MIT6.006] 7. Counting Sort, Radix Sort, Lower Bounds for Sorting 基数排序,基数排序,排序下界
在前6节课讲的排序方法(冒泡排序,归并排序,选择排序,插入排序,快速排序,堆排序,二分搜索树排序和AVL排序)都是属于对比模型(Comparison Model).对比模型的特点如下: 所有输入ite ...
- 基数排序(Radix Sort)
基数排序(Radix Sort) 第一趟:个位 收集: 第二趟:十位 第三趟:百位 3元组 基数排序--不是基于"比较"的排序算法 递增就是把收集的过程返过来 算法效率分析 需要r ...
- 【算法】基数排序(Radix Sort)(十)
基数排序(Radix Sort) 基数排序是按照低位先排序,然后收集:再按照高位排序,然后再收集:依次类推,直到最高位.有时候有些属性是有优先级顺序的,先按低优先级排序,再按高优先级排序.最后的次序就 ...
- 学习算法-基数排序(radix sort)卡片分类(card sort) C++数组实现
基数排序称为卡片分类,这是一个比较早的时间越多,排名方法. 现代计算机出现之前,它已被用于排序老式打孔卡. 说下基数排序的思想.前面我有写一个桶式排序,基数排序的思想是桶式排序的推广. 桶式排序:ht ...
- [Algorithm] Radix Sort Algorithm
For example we have the array like this: [, , , , , ] First step is using Counting sort for last dig ...
随机推荐
- jQuery form插件的使用--ajaxForm()和ajaxSubmit()
转载:https://blog.csdn.net/qq_38602656/article/details/78668924
- kafka删除主题数据和删除主题
1.删除主题 在server.properties中增加设置,默认未开启 delete.topic.enable=true 删除主题命令 /bin/kafka-topics --delete --to ...
- c语言中有关0和1的运算问题
/*有关0和1 的总结 最近做题总是混淆0 和 1 对于/ 和 %运算时候的结果怎么算 所以就上机试验了一番 结论: c语言中,0/任何数都为0 0%任何数都为0 1/任何数都为0 1%任何数都余1 ...
- ubuntu ifconfig 不显示IP地址
本文转载:https://blog.csdn.net/cmh477660693/article/details/52760236 ubuntu终端下命令ifconfig的问题解决 问题一. ifcon ...
- Vue.js-----轻量高效的MVVM框架(五、计算属性)
#基础例子 <div id="dr01"> <h4>#基础例子</h4> <div> num01={{num01}}, num02= ...
- OfficeControl插件的用法
项目中需要用到文档在线编辑的功能,网上找到这篇文章: http://hi.baidu.com/hurtingwings/item/bf83b6343305a94e3075a19e
- 移动测试之appium+python 导出报告(六)
下载 HTMLTestRunner.py python3可以参考这个地址 这是针对Python2.7版本 test.py from appium import webdriver import tim ...
- cookie 跨域访问
废话不知道该说些什么...先看代码吧. cookie 是浏览器保存在用户计算机上的少量数据 //读取cookie function getCookie(name) { var arr, reg = n ...
- 关于python的sort和sorted
1.sort无返回值,没有新建列表 例子: a=[2,1,3] print("a=",a) b=a.sort() print("a=",a) print(&q ...
- (转)Rsync命令详解
Rsync命令详解 原文:http://blog.51cto.com/irow10/1826249 说明: Rsync是linux/Unix文件同步和传送工具.用于替代rcp的一个工具,rsync可以 ...