• JAVA 数据结构 散列表的实现


    散列函数,主要目的是需找一个好的散列方法把这个数组的每一个位置都能均匀的用到,下面先上一个比较好的散列函数实现

     
    散列函数
     1 package com.wuxing;
     2 
     3 /**
     4  *  散列函数
     5  * @author wuxing
     6  *
     7  */
     8 public class Hash {
     9     
    10     /**
    11      * 
    12      * @param key  键值
    13      * @param tableSize  存放数组的长度
    14      * @return  存放键值在数组的位置
    15      */
    16     public static int hash(String key,int tableSize){
    17         int hashVal=0;
    18         for(int i=0;i<key.length();i++){
    19             hashVal=37*hashVal+key.charAt(i);
    20         }
    21         hashVal%=tableSize;
    22         if(hashVal<0)
    23         hashVal+=tableSize;
    24         return hashVal;
    25     }
    26     
    27     
    28     
    29 
    30 }

    然后对于散列表的实现,主要又分离散列表和开放地址法,分离散列表就是在一个数组中,如果对于有地址冲突的数据,则放在一个横向的链表中进行保存,具体实现如下

    分离散列表的实现
     1 package com.wuxing;
     2 
     3 import java.util.LinkedList;
     4 
     5 /**
     6  * 分离散列表的实现,如果有重复的数字,即有hash冲突,则放在横向的链表中保存
     7  * @author wuxing
     8  *
     9  */
    10 public class SeparateChainingHashTable {
    11     private static final int DEFAULT_TABLE_SIZE=101;
    12     
    13     //散列表的数组
    14     private LinkedList<Object>[] theLists;
    15     
    16     public  SeparateChainingHashTable(){
    17         this(DEFAULT_TABLE_SIZE);
    18     }
    19     
    20     public SeparateChainingHashTable(int size){
    21         theLists=new LinkedList[size];
    22         for(int i=0;i<theLists.length;i++){
    23             theLists[i]=new LinkedList<Object>();
    24         }
    25     }
    26     
    27     
    28     public void makeEmpty(){
    29         for(int i=0;i<theLists.length;i++){
    30             theLists[i].clear();
    31         }
    32     }
    33     
    34     public void remove(Hashable x){
    35         theLists[x.hash(theLists.length)].remove();
    36     }
    37     
    38     public Hashable find(Hashable x){
    39         return (Hashable)theLists[x.hash(theLists.length)]
    40     .get(0);}
    41 }
    42 
    43 
    44 interface Hashable{
    45     int hash(int tableSize);
    46 }

    对于开散列法,如果又地址冲突的数据,则进行查找下一个地址是否没有使用,如果没有使用则插入,比较流行的是平方探测法比较好

     
    开放地址法散列表
     1 package com.wuxing;
     2 
     3 import java.security.AllPermission;
     4 
     5  class HashEntry {
     6      Hashable element; //元素
     7      boolean isActive;//懒惰删除的实现标记
     8      
     9      public HashEntry(Hashable e,boolean i){
    10          element=e;
    11          isActive=i;
    12      }
    13 }
    14  
    15 class QuadraticProbingHashTable{
    16     private static final int DEFAULT_TABLE_SIZE=11;
    17     private HashEntry[] array;
    18     
    19     private int currentSize;
    20     
    21     public QuadraticProbingHashTable(){
    22         this(DEFAULT_TABLE_SIZE);
    23     }
    24 
    25     public QuadraticProbingHashTable(int defaultTableSize) {
    26         allocateArray(defaultTableSize);
    27         makeEmpty();
    28     }
    29 
    30     private void allocateArray(int defaultTableSize) {
    31         array=new HashEntry[defaultTableSize];
    32     }
    33 
    34     private void makeEmpty() {
    35         currentSize=0;
    36         for(int i=0;i<array.length;i++){
    37             array[i]=null;
    38         }
    39     }
    40     
    41     /**
    42      * 解决查找冲突问题
    43      * @param x
    44      * @return
    45      */
    46     private int findPos(Hashable x){
    47         int collisionNum=0;
    48         int currentPos=x.hash(array.length);
    49         
    50         while(array[currentPos]!=null&&!array[currentPos].element.equals(x)){
    51             currentPos+=2*++collisionNum-1;
    52             if(currentPos>array.length)
    53                     currentPos-=array.length;
    54         }
    55         return currentPos;
    56     }
    57     
    58     public Hashable find(Hashable x){
    59         int currentPos=findPos(x);
    60         return isActive(currentPos)?array[currentPos].element:null;
    61     }
    62 
    63     private boolean isActive(int currentPos) {
    64         return array[currentPos]!=null&&array[currentPos].isActive;
    65     }
    66     
    67 }

     

  • 相关阅读:
    sqlserver 分页
    sqlserver 用FOR XML PATH('')多行并成一列
    yarn的安装和使用
    redis安装及基本使用
    dbeaver 的界面乱码
    cypress测试框架(一)
    外网访问VMware虚拟机的Web服务---系列操作
    将博客搬至CSDN
    textgrid-python模块基础使用
    opencv通过mask掩码图合成两张图
  • 原文地址:https://www.cnblogs.com/jerryxing/p/2450848.html
Copyright © 2020-2023  润新知