• Java集合之Hashtable理论(散列表)


    除了使用链表的方法,更多的是用开放寻址法

    • 线性寻址

      (LH(k,0)=H(k))确定了整个探查序列,只有m种不同的探查序列

    • 二次寻址

      (QH(k,i)={H(k)+c_1*i+c_2*i^2} pmod m),其中(c_1)(c_2)是两个不为0的常数。若取(c_1=c_2=1),二次探查的散列函数为:

      private int QH(int value, int i)
      {
          return (H(value) + i + i * i) % 10;
      }
      

      对于数值 7,(QH())给出的探查序列是 7、9、3、9……由于初始位置(QH(k, 0) = H(k))确定了整个探查序列,所以二次探查同样只有 m 种不同的探查序列。通过让下一个探查位置以 i 的平方偏移,不容易像线性探查那样让被占用的槽连成一片。

    • 双重寻址

      (H(k,i)={H_1(k)+i*H_2(k)} pmod m)

      其中:

      (H_1(k)=k pmod m)

      (H_2(k)=1+{k pmod {m-1}})

      int H1(int value)
          {
              return value % _values.Length;
          }
          int H2(int value)
          {
              return 1 + (value % (_values.Length - 1));
          }
          int DH(int value, int i)
          {
              return (H1(value) + i * H2(value)) % _values.Length;
          }
       
          public void Add(int item)
          {
              int i = 0; // 已经探查过的槽的数量
              do
              {
                  int j = DH(item, i); // 想要探查的地址
                  if (_values[j] == null || (int)_values[j] == DELETED)
                  {
                      _values[j] = item;
                      return;
                  }
                  else
                  {
                      i += 1;
                  }
              } while (i <= _values.Length);
              throw new Exception("集合溢出");
          }
          public bool Contains(int item)
          {
              int i = 0; // 已经探查过的槽的数量
              int j = 0; // 想要探查的地址
              do
              {
                  j = DH(item, i);
                  if (_values[j] == null)
                      return false;
       
                  if ((int)_values[j] == item)
                      return true;
                  else
                      i += 1;
              } while (i <= _values.Length);
              return false;
          }
          public void Remove(int item)
          {
              int i = 0; // 已经探查过的槽的数量
              int j = 0; // 想要探查的地址
              do
              {
                  j = DH(item, i);
                  if (_values[j] == null)
                      return;
       
                  if ((int)_values[j] == item)
                  {
                      _values[j] = DELETED;
                      return;
                  }
                  else
                  {
                      i += 1;
                  }
              } while (i <= _values.Length);
          }
      

    总结

      此算法(双重探查)在C#中实现,但是在Java的Hashtable源码中,是以单向链表的方式实现hashtable(哈希表)的。

  • 相关阅读:
    智课雅思词汇---十八、前缀peri是什么意思
    新东方雅思词汇---7.1、probation
    智课雅思词汇---十七、前綴il-, in-, ir-, im-有什麼關係
    英语发音规则---U字母-[复习中]
    英语发音规则---O字母
    Android之Http沟通——4.Android HTTP索取信息:HttpClient
    一步一步的理解C++STL迭代器
    Java学习之路:ArrayList用法
    LeetCode:Remove Duplicates from Sorted Array
    【Struts2学习笔记(2)】Action默认值和配置Action于result各种转发类型
  • 原文地址:https://www.cnblogs.com/flyingrun/p/12747838.html
Copyright © 2020-2023  润新知