哈希表,开放地址法之再哈希代码(JAVA)

  哈希表中,一串连续的已填充单元叫做填充序列。增加越来越多的数据项时,填充序列变的越来越长,这叫做聚集。






为了消除原始聚集和二次聚集,可以使用另外的一个方法:再哈希法:一种依赖关键字的探测序列,而不是每个关键字都一样,那么,不同的关键字即使映射到相同的数组下标,也可以使用不同的探测序列。
方法是把关键字用不同的哈希函数再做一次哈希化,用这个结果作步长,对指定的关键字,步长在整个探测中是不变的,不同的关键字使用不同的步长。



数组实现的哈希表,开放地址法之再哈希法:

Java代码 复制代码 收藏代码
  1. import java.io.*;
  2. class DataItem {//数据项
  3. private int iData; // 数据项的关键字
  4. public DataItem(int ii)
  5. { iData = ii; }
  6. public int getKey()
  7. { return iData; }
  8. }
  9. class HashTable{//数组实现的哈希表,开放地址法之再哈希法
  10. private DataItem[] hashArray; //存数据的数组
  11. private int arraySize;
  12. private DataItem nonItem; //已删除标志
  13. HashTable(int size) {//哈希表构造函数
  14. arraySize = size;
  15. hashArray = new DataItem[arraySize];
  16. nonItem = new DataItem(-1);
  17. }
  18. public void displayTable()//输出哈希表
  19. {
  20. System.out.print("Table: ");
  21. for(int j=0; j<arraySize; j++)
  22. {
  23. if(hashArray[j] != null)
  24. System.out.print(hashArray[j].getKey()+ " ");
  25. else
  26. System.out.print("** ");
  27. }
  28. System.out.println("");
  29. }
  30. //哈希函数1
  31. public int hashFunc1(int key){
  32. return key % arraySize;
  33. }
  34. //哈希函数2,不同于哈希函数1,用于再哈希。
  35. public int hashFunc2(int key){
  36. // array size must be relatively prime to 5, 4, 3, and 2
  37. return 5 - key % 5;
  38. }
  39. //哈希表中插入数据
  40. public void insert(int key, DataItem item){
  41. int hashVal = hashFunc1(key); //求关键字的哈希值
  42. int stepSize = hashFunc2(key); // 再探测步长的大小
  43. while(hashArray[hashVal] != null && hashArray[hashVal].getKey() != -1) {
  44. hashVal += stepSize; //单元被占用,再探测
  45. hashVal %= arraySize;
  46. }
  47. hashArray[hashVal] = item;
  48. }
  49. //在哈希表中删除
  50. public DataItem delete(int key) {
  51. int hashVal = hashFunc1(key);
  52. int stepSize = hashFunc2(key);
  53. while(hashArray[hashVal] != null){//直到一个空单元出现
  54. if(hashArray[hashVal].getKey() == key){
  55. DataItem temp = hashArray[hashVal];
  56. hashArray[hashVal] = nonItem; //作删除标记
  57. return temp;
  58. }
  59. hashVal += stepSize; //再探测
  60. hashVal %= arraySize;
  61. }
  62. return null;
  63. }
  64. //在哈希表中搜索
  65. public DataItem find(int key){
  66. int hashVal = hashFunc1(key);
  67. int stepSize = hashFunc2(key);
  68. while(hashArray[hashVal] != null) {
  69. if(hashArray[hashVal].getKey() == key)
  70. return hashArray[hashVal];
  71. hashVal += stepSize;
  72. hashVal %= arraySize;
  73. }
  74. return null;
  75. }
  76. }
  77. public class HashDoubleApp{
  78. public static void main(String[] args) throws IOException{
  79. int aKey;
  80. DataItem aDataItem;
  81. int size, n;
  82. System.out.print("Enter size of hash table: ");
  83. size = getInt();
  84. System.out.print("Enter initial number of items: ");
  85. n = getInt();
  86. HashTable theHashTable = new HashTable(size);
  87. for(int j=0; j<n; j++){
  88. aKey = (int)(java.lang.Math.random() * 2 * size);
  89. aDataItem = new DataItem(aKey);
  90. theHashTable.insert(aKey, aDataItem);
  91. }
  92. while(true){
  93. System.out.print("Enter first letter of ");
  94. System.out.print("show, insert, delete, or find: ");
  95. char choice = getChar();
  96. switch(choice)
  97. {
  98. case 's':
  99. theHashTable.displayTable();
  100. break;
  101. case 'i':
  102. System.out.print("Enter key value to insert: ");
  103. aKey = getInt();
  104. aDataItem = new DataItem(aKey);
  105. theHashTable.insert(aKey, aDataItem);
  106. break;
  107. case 'd':
  108. System.out.print("Enter key value to delete: ");
  109. aKey = getInt();
  110. theHashTable.delete(aKey);
  111. break;
  112. case 'f':
  113. System.out.print("Enter key value to find: ");
  114. aKey = getInt();
  115. aDataItem = theHashTable.find(aKey);
  116. if(aDataItem != null)
  117. System.out.println("Found " + aKey);
  118. else
  119. System.out.println("Could not find " + aKey);
  120. break;
  121. default:
  122. System.out.print("Invalid entry\n");
  123. }
  124. }
  125. }
  126. public static String getString() throws IOException
  127. {
  128. InputStreamReader isr = new InputStreamReader(System.in);
  129. BufferedReader br = new BufferedReader(isr);
  130. String s = br.readLine();
  131. return s;
  132. }
  133. public static char getChar() throws IOException
  134. {
  135. String s = getString();
  136. return s.charAt(0);
  137. }
  138. public static int getInt() throws IOException
  139. {
  140. String s = getString();
  141. return Integer.parseInt(s);
  142. }
  143. }
import java.io.*;

class DataItem {//数据项                            
   private int iData;  // 数据项的关键字

   public DataItem(int ii)  
      { iData = ii; }

   public int getKey()
      { return iData; }

   } 

class HashTable{//数组实现的哈希表,开放地址法之再哈希法
   private DataItem[] hashArray; //存数据的数组
   private int arraySize;
   private DataItem nonItem;  //已删除标志

   HashTable(int size) {//哈希表构造函数 
      arraySize = size;
      hashArray = new DataItem[arraySize];
      nonItem = new DataItem(-1);
   }

   public void displayTable()//输出哈希表
      {
      System.out.print("Table: ");
      for(int j=0; j<arraySize; j++)
         {
         if(hashArray[j] != null)
            System.out.print(hashArray[j].getKey()+ " ");
         else
            System.out.print("** ");
         }
      System.out.println("");
      }

  //哈希函数1
   public int hashFunc1(int key){
      return key % arraySize;
   }

   //哈希函数2,不同于哈希函数1,用于再哈希。
   public int hashFunc2(int key){
    // array size must be relatively prime to 5, 4, 3, and 2
      return 5 - key % 5;
      }

   //哈希表中插入数据
   public void insert(int key, DataItem item){
      int hashVal = hashFunc1(key);  //求关键字的哈希值
      int stepSize = hashFunc2(key); // 再探测步长的大小
                                   
      while(hashArray[hashVal] != null && hashArray[hashVal].getKey() != -1) {
         hashVal += stepSize;   //单元被占用,再探测   
         hashVal %= arraySize;    
         }
      hashArray[hashVal] = item;    
      } 

   //在哈希表中删除
   public DataItem delete(int key) {
      int hashVal = hashFunc1(key);  
      int stepSize = hashFunc2(key);  

      while(hashArray[hashVal] != null){//直到一个空单元出现
          if(hashArray[hashVal].getKey() == key){
            DataItem temp = hashArray[hashVal]; 
            hashArray[hashVal] = nonItem;  //作删除标记
            return temp;     
            }
         hashVal += stepSize; //再探测
         hashVal %= arraySize;  
         }
      return null;        
      }  

   //在哈希表中搜索
   public DataItem find(int key){
      int hashVal = hashFunc1(key);  
      int stepSize = hashFunc2(key);  

      while(hashArray[hashVal] != null) { 
         if(hashArray[hashVal].getKey() == key)
            return hashArray[hashVal]; 
         hashVal += stepSize;  
         hashVal %= arraySize;  
         }
      return null;    
      }

   } 
 public class HashDoubleApp{
   public static void main(String[] args) throws IOException{
      int aKey;
      DataItem aDataItem;
      int size, n;
                      
      System.out.print("Enter size of hash table: ");
      size = getInt();
      System.out.print("Enter initial number of items: ");
      n = getInt();
                               
      HashTable theHashTable = new HashTable(size);

      for(int j=0; j<n; j++){
         aKey = (int)(java.lang.Math.random() * 2 * size);
         aDataItem = new DataItem(aKey);
         theHashTable.insert(aKey, aDataItem);
      }

      while(true){
         System.out.print("Enter first letter of ");
         System.out.print("show, insert, delete, or find: ");
         char choice = getChar();
         switch(choice)
            {
            case 's':
               theHashTable.displayTable();
               break;
            case 'i':
               System.out.print("Enter key value to insert: ");
               aKey = getInt();
               aDataItem = new DataItem(aKey);
               theHashTable.insert(aKey, aDataItem);
               break;
            case 'd':
               System.out.print("Enter key value to delete: ");
               aKey = getInt();
               theHashTable.delete(aKey);
               break;
            case 'f':
               System.out.print("Enter key value to find: ");
               aKey = getInt();
               aDataItem = theHashTable.find(aKey);
               if(aDataItem != null)
                  System.out.println("Found " + aKey);
               else
                  System.out.println("Could not find " + aKey);
               break;
            default:
               System.out.print("Invalid entry\n");
            }  
         }  
      }  

   public static String getString() throws IOException
      {
      InputStreamReader isr = new InputStreamReader(System.in);
      BufferedReader br = new BufferedReader(isr);
      String s = br.readLine();
      return s;
      }

   public static char getChar() throws IOException
      {
      String s = getString();
      return s.charAt(0);
      }

   public static int getInt() throws IOException
      {
      String s = getString();
      return Integer.parseInt(s);
      }

   } 


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值