链地址法处理Hash冲突

   哈希表中的每个位置称为桶(bucket),当发生哈希冲突时就以链表形式存放多个元素。


链地址法处理Hash冲突,看看下面代码,模拟了JDK中的HashSet:
Java代码   收藏代码
  1. class  Node{ //节点数据结构    
  2.     private  Object value; //节点的值    
  3.     private  Node next; //链表中指向下一结点的引用    
  4.   
  5.     /*提供了常见的操作*/    
  6.     public  Node(Object value){ this .value = value;};   
  7.     public  Object getValue() { return  value;}   
  8.     public  Node getNext() { return  next;}   
  9.     public   void  setNext(Node next){ this .next=next;}   
  10. }   
  11.   
  12. public   class  MyHashSet { //Hash数据结构    
  13.     private  Node[] array; //存储数据链表的数组    
  14.     private   int  size =  0 ; //表示集合中存放的对象的数目    
  15.     public  MyHashSet( int  length){   
  16.         array = new  Node[length]; //创建数组    
  17.     }   
  18.   
  19.     public   int  size(){  
  20.      return  size;  
  21.     }  
  22.    
  23.     private   static   int  hash (Object o){     //根据对象的哈希码得到一个优化的哈希码,    
  24.                                         //算法参照java.util.HashMap的hash()方法    
  25.         int  h = o.hashCode();   
  26.         h += ~(h<<9 );   
  27.         h ^= (h>>>14 );   
  28.         h += (h<<4 );   
  29.         h ^= (h>>>10 );   
  30.         return  h;   
  31.     }  
  32.    
  33.     private   int  indexFor( int  hashCode){     //根据Hash码得到其索引位置    
  34.                                         //算法参照java.util.HashMap的indexFor()方法    
  35.         return  hashCode & (array.length- 1 );   
  36.     }   
  37.   
  38.     public   void  add(Object value) { //把对象加入集合,不允许加入重复的元素    
  39.         int  index = indexFor(hash(value)); //先根据value得到index    
  40.         System.out.println("index:"  + index +  " value:"  + value);   
  41.         Node newNode = new  Node(value); //由value创建一个新节点newNode    
  42.         Node node = array[index];//由index得到一个节点node    
  43.   
  44.         if  (node ==  null ) { //若这个由index得到的节点是空,则将新节点放入其中    
  45.             array[index]=newNode;   
  46.             size++;   
  47.         } else  {  
  48. //若不为空则遍历这个点上的链表(下一个节点要等于空或者该节点不等于新节点的值--不允许重复)    
  49.         Node nextNode;   
  50.        while  (!node.getValue().equals(value) && (nextNode = node.getNext())!= null ) {   
  51.                 node = nextNode;   
  52.             }   
  53.             if  (!node.getValue().equals(value)) {  
  54.              //若值不相等则加入新节点    
  55.                 node.setNext(newNode);   
  56.                 size++;   
  57.             }   
  58.         }   
  59.     }   
  60.   
  61.   
  62.     public   boolean  contains(Object value){   
  63.         int  index = indexFor(hash(value));   
  64.         Node node = array[index];   
  65.         while  (node!= null  && !node.getValue().equals(value)) {   
  66.             node = node.getNext();   
  67.         }//横向查找    
  68.         if  (node!= null  && node.getValue().equals(value)) {   
  69.             return   true ;   
  70.         } else  {   
  71.             return   false ;   
  72.         }   
  73.     }   
  74.   
  75.     public   boolean  remove(Object value) {   
  76.         int  index = indexFor(hash(value));   
  77.         Node node = array[index];   
  78.         if  (node!= null  && node.getValue().equals(value)) { //若是第一个节点就是要remove的    
  79.             array[index]=node.getNext();   
  80.             size--;   
  81.             return   true ;   
  82.         }   
  83.         Node lastNode = null ;   
  84.         while  (node!= null  && !node.getValue().equals(value)) { //若不是第一个节点就横向查找    
  85.             lastNode = node;//记录上一个节点    
  86.             node = node.getNext();   
  87.         }   
  88.         if  (node!= null  && node.getValue().equals(value)) {   
  89.             lastNode.setNext(node.getNext());   
  90.             size--;   
  91.             return   true ;   
  92.         }else  {   
  93.             return   false ;   
  94.         }   
  95.     }   
  96.   
  97.     public  Object[] getAll() {   
  98.         Object [] values = new  Object[size];   
  99.         int  index =  0 ;   
  100.         for  ( int  i =  0 ; i < array.length; i++) {   
  101.             Node node = array[i];   
  102.             while  (node!= null ) {   
  103.                 values[index++]=node.getValue();   
  104.                 node = node.getNext();   
  105.             }      
  106.         }   
  107.         return  values;      
  108.     }   
  109.     public   static   void  main(String[] args) {   
  110.         MyHashSet set = new  MyHashSet( 6 );   
  111.         Object [] values = {"Tom" , "Mike" , "Mike" , "Jack" , "Mary" , "Linda" , "Rose" , "Jone" };   
  112.         for  ( int  i =  0 ; i < values.length; i++) {   
  113.             set.add(values[i]);   
  114.         }   
  115.         set.remove("Mary" );   
  116.         System.out.println("size=" +set.size());   
  117.         values = set.getAll();   
  118.         for  ( int  i =  0 ; i < values.length; i++) {   
  119.             System.out.println(values[i]);   
  120.         }   
  121.         System.out.println(set.contains("Jack" ));   
  122.         System.out.println(set.contains("Linda" ));   
  123.         System.out.println(set.contains("Jane" ));   
  124.     }   
  125. }   



结果:
index:4 value:Tom
index:1 value:Mike
index:1 value:Mike
index:5 value:Jack
index:5 value:Mary
index:0 value:Linda
index:0 value:Rose
index:0 value:Jone
size=6
Linda
Rose
Jone
Mike
Tom
Jack
true
true
false
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值