设为首页收藏本站Access中国

Office中国论坛/Access中国论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

返回列表 发新帖
查看: 2431|回复: 1
打印 上一主题 下一主题

【原创】测一下Hashtable的排序规则

[复制链接]
跳转到指定楼层
1#
发表于 2014-2-24 11:16:09 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
[size=14.399999618530273px]表面上是无规律的,实际上还是有规律的。
[size=14.399999618530273px]

[size=14.399999618530273px]
  1. using System;
  2. using System.Collections;
  3. class MyClass
  4. {
  5.     static readonly int[] primes =
  6.      {
  7.         3, 7, 11, 17, 23, 29, 37, 47, 59, 71, 89, 107, 131, 163, 197, 239, 293, 353, 431, 521, 631, 761, 919,
  8.         1103, 1327, 1597, 1931, 2333, 2801, 3371, 4049, 4861, 5839, 7013, 8419, 10103, 12143, 14591,
  9.         17519, 21023, 25229, 30293, 36353, 43627, 52361, 62851, 75431, 90523, 108631, 130363, 156437,
  10.         187751, 225307, 270371, 324449, 389357, 467237, 560689, 672827, 807403, 968897, 1162687, 1395263,
  11.         1674319, 2009191, 2411033, 2893249, 3471899, 4166287, 4999559, 5999471, 7199369
  12.      };
  13.     static int GetHashcode(object key, int k, int hashsize)
  14.     {
  15.         //Hk(key) = [GetHash(key) + k * (1 + (((GetHash(key) >> 5) + 1) % (hashsize – 1)))] % hashsize
  16.         int k_code = key.GetHashCode();
  17.         return Math.Abs(k_code + k * (1 + (((k_code >> 5) + 1) % (hashsize - 1)))) % hashsize;
  18.     }
  19.     static void Print(Hashtable hs)
  20.     {
  21.         Console.WriteLine("============Hashtable Test=================");
  22.         foreach (string key in hs.Keys)
  23.         {
  24.             Console.WriteLine("Hk(key):{0:0000},Key:{1}", GetHashcode(key, 1, 7), key);
  25.         }
  26.     }
  27.     static void Main(string[] args)
  28.     {
  29.         //public Hashtable(int capacity, float loadFactor);
  30.         //Hashtable hs = new Hashtable { 1, 2, 3, 4, 5, };
  31.         //测试C
  32.         Hashtable hashC = new Hashtable(7);
  33.         hashC.Add("5", "顺序1");
  34.         hashC.Add("1", "顺序1");
  35.         hashC.Add("6", "顺序2");
  36.         hashC.Add("4", "顺序2");
  37.         hashC.Add("3", "顺序3");//<-EndPos(操作完后移动到下一个位置,即"4")
  38.         Print(hashC);
  39.         Console.WriteLine("add all");
  40.         //0123456<==capacity(容量)=7
  41.         // 1 3456<==最后一次操作的下一位置
  42.         //   ^^
  43.         // 4 5123<==指针移动顺序  

  44.         hashC.Remove("0");
  45.         Print(hashC);
  46.         Console.WriteLine("hashC.Remove('0');");
  47.         hashC.Remove("0");
  48.         Print(hashC);
  49.         Console.WriteLine("hashC.Remove('0');");
  50.         hashC.Remove("4");//删除指针下移
  51.         Print(hashC);
  52.         Console.WriteLine("hashC.Remove('4');");
  53.         hashC.Remove("0");
  54.         Print(hashC);
  55.         Console.WriteLine("hashC.Remove('4');");
  56.         hashC.Add("2", "---");//添加不移动指针?!这次没动
  57.         Print(hashC);
  58.         Console.WriteLine("hashC.Add('2');");
  59.         
  60.         Console.ReadKey();
  61.     }
  62. }
复制代码



[size=14.399999618530273px]

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享分享 分享淘帖 订阅订阅
2#
 楼主| 发表于 2014-2-24 11:16:23 | 只看该作者
结果如下:

============Hashtable Test=================
Hk(key):0004,Key:4
Hk(key):0005,Key:5
Hk(key):0006,Key:6
Hk(key):0001,Key:1
Hk(key):0003,Key:3
add all
============Hashtable Test=================
Hk(key):0004,Key:4
Hk(key):0005,Key:5
Hk(key):0006,Key:6
Hk(key):0001,Key:1
Hk(key):0003,Key:3
hashC.Remove('0');
============Hashtable Test=================
Hk(key):0004,Key:4
Hk(key):0005,Key:5
Hk(key):0006,Key:6
Hk(key):0001,Key:1
Hk(key):0003,Key:3
hashC.Remove('0');
============Hashtable Test=================
Hk(key):0005,Key:5
Hk(key):0006,Key:6
Hk(key):0001,Key:1
Hk(key):0003,Key:3
hashC.Remove('4');
============Hashtable Test=================
Hk(key):0005,Key:5
Hk(key):0006,Key:6
Hk(key):0001,Key:1
Hk(key):0003,Key:3
hashC.Remove('4');
============Hashtable Test=================
Hk(key):0005,Key:5
Hk(key):0006,Key:6
Hk(key):0001,Key:1
Hk(key):0002,Key:2
Hk(key):0003,Key:3
hashC.Add('2');

[1]测试了键值hashcode无冲突情况
[2]容量指定为第一个给定素数=7
[3]内部停留指针所在的位置:最后操作的位置向下移动一格
[4]Foreach时,从HeadPos开始,按顺序输出,容器可以看作一个环形队列
[5]字符的hashcode与Hk(key)完全一样



Hashcode分配规律:
[1]默认值的情况
3(素数表中的第一个情况)



[2]给定初始值的情况
如果给定初始值,它会在素数表中找比设置大小大的数的最小值。



[3]自然增长的情况
首个3,再表中取比这个数的两倍大的最小值,依次类推。

3 -> 7 -> 17 -> 37 -> 89 -> 197 -> 431 -> 919 -> 1931 -> 4049 -> 8419 -> 17519 -> 36353 -> 75431 -> ...


[4]给定初始值自然增长情况
参照[3],区别在于首字符的设定

[5]素数间隔
从23开始,后一个素数/前一个素数,约等于1.2
您需要登录后才可以回帖 登录 | 注册

本版积分规则

QQ|站长邮箱|小黑屋|手机版|Office中国/Access中国 ( 粤ICP备10043721号-1 )  

GMT+8, 2024-5-7 13:30 , Processed in 0.086258 second(s), 25 queries .

Powered by Discuz! X3.3

© 2001-2017 Comsenz Inc.

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