找回密码
 欢迎注册
楼主: silitex

[原创] 位排序 -- 基于计数排序和基数排序产生的特例

[复制链接]
发表于 2009-11-3 16:25:47 | 显示全部楼层
while (i bitx(X [ j],k) //元素想x[ i ]的第k比特大于X[j]的第k比特 X [i ] <--> X[ j ] //交换x[ i ]与x[j] i++; j--; }
这个逻辑有问题,等我有空儿时订正它。
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2009-11-3 18:39:22 | 显示全部楼层
本帖最后由 liangbch 于 2009-11-3 18:43 编辑 以下是我写的位排序代码,包含排序函数和测试程序
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <memory.h>
  4. typedef unsigned long DWORD;
  5. typedef int BOOL;
  6. #define TRUE 1
  7. #define FALSE 0
  8. #define MAX_LEN 65536
  9. DWORD data[MAX_LEN];
  10. DWORD databak[MAX_LEN];
  11. void printArray(DWORD *p, int len);
  12. //bit 排序核心算法,这是一个递归函数
  13. void bitSort(DWORD *p, int begin, int end, DWORD mask )
  14. {
  15. int i=begin;
  16. int j=end;
  17. if ( j==i+1 && p[j]>=p[ i ])
  18. return;
  19. if ( mask<=0)
  20. return ;
  21. while (i<j)
  22. {
  23. DWORD t;
  24. while ( (p[ i ] & mask) ==0 && i<=end)
  25. i++;
  26. while ( (p[j] & mask) >0 && j>=begin)
  27. j--;
  28. if (i<j)
  29. {
  30. t=p[ i ];
  31. p[ i ]=p[j];
  32. p[j]=t;
  33. }
  34. }
  35. mask/=2; i--; j++;
  36. if (i>begin)
  37. {
  38. bitSort(p,begin,i,mask);
  39. }
  40. if (j<end)
  41. {
  42. bitSort(p,j,end,mask);
  43. }
  44. }
  45. //使用 bit sort 对数组p 进行排序
  46. void mySort1(DWORD *p, int len)
  47. {
  48. DWORD max=p[0];
  49. DWORD mask=2147483648;
  50. int i;
  51. if (len<2)
  52. return;
  53. for (i=1;i<len;i++)
  54. {
  55. if (p [ i ] > max)
  56. max=p[ i ];
  57. }
  58. while ( mask > max)
  59. mask/=2;
  60. bitSort(p,0,len-1,mask);
  61. }
  62. //打印数组
  63. void printArray(DWORD *p, int len)
  64. {
  65. int i;
  66. for (i=0;i<len;i++)
  67. {
  68. if (i>0)
  69. printf(",");
  70. printf("%u",p[ i ]);
  71. }
  72. printf("\n");
  73. }
  74. //检查数组是否是增序排列
  75. BOOL checkArray(DWORD *p,int len)
  76. {
  77. int i;
  78. BOOL ret=TRUE;
  79. for (i=0;i<len-1;i++)
  80. {
  81. if (p[i+1]< p[ i ] )
  82. {
  83. ret=FALSE; break;
  84. }
  85. }
  86. return ret;
  87. }
  88. //bit排序测试程序,产生1 到 MAX_LEN,对长度为1到 MAX_LEN的数组进行排序
  89. void testBitSort()
  90. {
  91. int i,j;
  92. for (i=1;i<=MAX_LEN;i++)
  93. {
  94. for (j=0;j<i;j++)
  95. {
  96. data[j]= (rand() & 255);
  97. }
  98. memcpy(databak,data,i*sizeof(DWORD));
  99. mySort1(data,i);
  100. if ( !checkArray(data,i) )
  101. {
  102. printf("error\n");
  103. printf("Before sort\n\t");
  104. printArray(databak,i);
  105. printf("After sort\n\t");
  106. printArray(data,i);
  107. break;
  108. }
  109. }
  110. }
  111. int main(int argc, char* argv[])
  112. {
  113. testBitSort();
  114. return 0;
  115. }
复制代码
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2009-11-3 18:52:12 | 显示全部楼层
10# liangbch 当关键字的范围很窄是,可比较 ( p[ i ] - min)的第k比特,速度可大大加快。比如有1百万个数,关键字的范围为 1000000 到 1000200。 则其复杂度为 8*1百万,因为 p[ i ] - min 的范围为0 到 200, 第1遍检测 bit7,第2遍检测 bit6,第8遍检测 bit0。
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
 楼主| 发表于 2009-11-4 08:55:51 | 显示全部楼层
本帖最后由 silitex 于 2009-11-4 09:15 编辑
10# liangbch 当关键字的范围很窄是,可比较 ( p[ i ] - min)的第k比特,速度可大大加快。比如有1百万个数,关键字的范围为 1000000 到 1000200。 则其复杂度为 8*1百万,因为 p[ i ] - min 的范围为0 到 200, ... liangbch 发表于 2009-11-3 18:52
感谢您的回答,程序中也考虑了关键字很窄的时候的范围,比如取值范围为:1000000 到 1000200,是则Hash成:0~200,那么就等于用8位(2^8=256)排序即可!(传入了UNIQUE_HASH_CALLBACK pUniqueHashFunc这个参数就是为了针对每一个不同的数据传入不同的Hash函数,以便做特殊处理) 您的算法我再花时间看看!
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
 楼主| 发表于 2009-11-4 09:00:31 | 显示全部楼层
本帖最后由 silitex 于 2009-11-4 14:11 编辑
关于位排序,前人已有研究。请看 http://bbs.emath.ac.cn/viewthrea ... &fromuid=25#pid9829。 快速扫了你代码中的注释,感觉你的这个实现不太好,需要分配额外的空间。 《无符号整数按位快速排序算法》基本思想是 ... liangbch 发表于 2009-11-3 15:02
呵呵,在写完这个位排序算法的时候,我看的就是您提供的前人的位排序算法,后来经过VC的单步跟踪,发现前人的位排序算法在边值判断上(会有重复判断的可能)要处理得没有那么好。 也很感谢您的批评和指正! 哎,做了一件前人做过的事情,还好这个事情不难做,没浪费多少时间!
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
 楼主| 发表于 2009-11-4 09:09:47 | 显示全部楼层
看完了您的代码: 其中: # if (i # while ( (p[ i ] & mask) ==0 && i<=end) # i++; # while ( (p[j] & mask) >0 && j>=begin) # j--;
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2009-11-4 11:31:11 | 显示全部楼层
哈哈,说点儿题外话,个人感觉那篇论文的代码很复杂,而且有错,不能编译。感觉作者的编程功底不是很好。现在有好多“学者”,就是为了写论文写论文。 你的代码写的很工整!不错!
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2009-11-4 11:35:08 | 显示全部楼层
7# silitex 学术氛围使然,有些人就是喜欢弄虚作假。
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2009-11-4 12:18:27 | 显示全部楼层
看完了您的代码: 其中: # if (i=begin) # j--; silitex 发表于 2009-11-4 09:09
很不幸,你的修改时错的,你增加i++,j--这行代码,然后运行一下我的测试程序就明白了。
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2009-11-4 12:31:35 | 显示全部楼层
看了一下周建钦写的那篇文章,本质上和我的代码是一致的。
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
您需要登录后才可以回帖 登录 | 欢迎注册

本版积分规则

小黑屋|手机版|数学研发网 ( 苏ICP备07505100号 )

GMT+8, 2024-11-22 12:35 , Processed in 0.024770 second(s), 14 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表