自己写的一个线性复杂度(16n)排序算法用到二叉树和哈希思想,多线程优化和大量数据分块排序都很好弄

哈咯哈咯131313 2018-04-14 12:19:46
作者:王为涛
最近无聊时候,就想起来大学想做的个哈希排序算法,就又按哈希的思想做了个优化版的排序算法,请大家指教。
注: 写的时候没有参考其他的排序算法,如果有意外和某些已发表的算法重和的话,还请告知,我做描述修改。

算法步骤:
1. 使用二进制1000 0000 0000 0000 作为第一层的哈希函数,与数组中的数做&操作,将数组分成大数组和小数组,覆盖到原始数组中,并保存各自的开始和结束的下标,供下层递归做循环范围使用。
2. 将哈希函数右移1位,和起止范围送入下一层递归中,重复上步骤的操作,将小数组中再分为一个大数组和小数组,继续递归,直到哈希函数为1或者待递归的范围为1了。
3.递归结束后,原始数组中数字就有序了。

稳定性:
排序时,小数组会从左到右插入数据,可以保持稳定性,大数组从右到左插入数据,如果需要保持稳定性的话,可以将大数组写入原始数组时从右向左遍历插入,可以保持稳定性。
下面的演示程序没有保持稳定性。

算法性能:
算法的时间复杂度是 <O(16n),因为很多大小数组分到最后可能只有一个数了,就不往下分了,会减少递归的层数,递归的层数是根据排序的变量类型和范围决定的,我这里用的0-32760间的数字,所以使用了16位的哈希函数,如果是32位的数字就需要32n的时间复杂度了。
算法的空间复杂度是O(n),使用了n个长度的临时空间做缓存,然后单线程递归时,只保留了16个现场,其中使用的临时变量较少,加上环境压栈所占也很小。同时,可以很容易的将递归操作改成16层的循环操作,可以节省环境压栈所用的空间。

多线程优化:
如果电脑性能较好,多线程能力十分强劲,在第一层递归时,直接使用多线程执行两条分支,这样到最下面一层会产生2的16次方的线程数,很久没用c语言了,线程方面的东西基本忘干净了,了解的网友可以说下。
if(start<n)
fun(p,q,start,n,tempn);
if(m<end)
fun(p,q,m+1,end,tempn);

大量数据分块排序:
如果数据量十分巨大,可以每次读取一定数据,然后写入硬盘中,然后下次递归重新读取硬盘中的数据,直到满足空间可容纳的时候,可以在内存中进行排序,然后将结果写入硬盘。


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>

#define MAX 1000000

void fun(int *p,int *q,int start,int end , int hashn){
int n=start;
int m=end-1;
int i;
for(i=start;i<end;i++){
if((p[i]&hashn) == 0){
q[n++] = p[i];
}else {
q[m--] = p[i];
}
}
for(i=start;i<end;i++){
p[i]= q[i];
}
if(hashn == 1){
return ;
} else {
int tempn = hashn >>1;
if(start<n)
fun(p,q,start,n,tempn);
if(m<end)
fun(p,q,m+1,end,tempn);
}
}
void main(){
unsigned int arr[MAX];
unsigned int temp[MAX];
clock_t startt,finish;
unsigned int hashn = 0x8000;
srand(time(0));
int i;
printf("开始随机生成数组%ld\n",clock());
for(i=0;i<MAX;i++){
arr[i]= rand()&32760;
}
printf("结束随即生成数组%ld\n",clock());
startt = clock();
fun(arr,temp,0,MAX,hashn);
finish = clock();
printf("执行时长%f\n",(double)(finish-startt)/CLOCKS_PER_SEC);
}


转载请附上此地址
...全文
926 4 打赏 收藏 转发到动态 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
哈咯哈咯131313 2018-05-16
  • 打赏
  • 举报
回复
额。。你自己试试就是了。。使用递归就必须是e^n是谁教给你的。。摊手
Symfund 2018-04-25
  • 打赏
  • 举报
回复
使用递归的算法是很low的!
Symfund 2018-04-23
  • 打赏
  • 举报
回复
任何算法使用了递归,其复杂度能O(n)? 最起码是e^n吧,最好的是log(n)
哈咯哈咯131313 2018-04-14
  • 打赏
  • 举报
回复
100万条排序大概0.17s

33,007

社区成员

发帖
与我相关
我的任务
社区描述
数据结构与算法相关内容讨论专区
社区管理员
  • 数据结构与算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧