Java学习者论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

手机号码,快捷登录

恭喜Java学习者论坛(https://www.javaxxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,购买链接:点击进入购买VIP会员
JAVA高级面试进阶视频教程Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程

Go语言视频零基础入门到精通

Java架构师3期(课件+源码)

Java开发全终端实战租房项目视频教程

SpringBoot2.X入门到高级使用教程

大数据培训第六期全套视频教程

深度学习(CNN RNN GAN)算法原理

Java亿级流量电商系统视频教程

互联网架构师视频教程

年薪50万Spark2.0从入门到精通

年薪50万!人工智能学习路线教程

年薪50万!大数据从入门到精通学习路线年薪50万!机器学习入门到精通视频教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程 MySQL入门到精通教程
查看: 272|回复: 0

[集合学习]用开放地址法写哈希表(HashTable)

[复制链接]
  • TA的每日心情
    开心
    2021-3-12 23:18
  • 签到天数: 2 天

    [LV.1]初来乍到

    发表于 2014-10-29 23:56:19 | 显示全部楼层 |阅读模式
    这个实例说明了如何写自已的哈希表,这是一种产生冲突时线性查找的方法,下面是代码
        package arithmetic;
        import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStreamReader;
        /**
    * 数据项类
    * 用来表示数据
    * @author 星情
    *
    */
    class DataItem {
         private int iData = 0;
         
         public DataItem(int iData) {
             this.iData = iData;
         }
         
         public int getKey() {
             return iData;
         }
    }
        /**
    * 产生聚集时使用的线性查找
    * @author 星情
    *
    */
    class HashTable {
         //数组
         private DataItem[] hashArray = null;
         //数组大小
         private int arraySize = 0;
         private DataItem nonItem = null;
         
         /**
          * 哈希表初始化
          * 其中设定一个占位项,即没有实际这样的数值,但是占位进行操作的一项
          * @param size 初始化大小
          */
         public HashTable(int size) {
             arraySize = size;
             hashArray = new DataItem[arraySize];
             nonItem = new DataItem(-1);
         }
         
         /**
          * 打印输出结果
          *
          */
         public void displayTable() {
             System.out.println("Table:");
             for (int i = 0; i < arraySize; i++) {
                 if (hashArray != null)
                     System.out.print(hashArray.getKey() + " ");
                 else
                     System.out.print("** ");
             }
             System.out.println();
         }
         
         /**
          * 哈希函数,计算哈希码
          * @param key 一个用来转换为哈希码的数字,这里就是DataItem的key
          * @return 哈希码
          */
         private int hashFunc(int key) {
             return key % arraySize;
         }
         
         /**
          * 插入新的元素
          * @param item 要插入的元素,必须是DataItem类型的
          */
         public void insert(DataItem item) {
             //获得DataItem的key
             int key = item.getKey();
             //通过哈希函数计算出哈希码
             int hashVal = this.hashFunc(key);
             
             //寻找能插入该元素的位置
             //这个位置不能为空,也不能是占位的那个元素,即nonItem
             while (hashArray[hashVal] != null && hashArray[hashVal] != nonItem) {
                 hashVal++;
                 //当线性查找到末尾的时候,应该从头查找
                 //这句等于if(hashVal == arraySize) hashVal = 0;
                 hashVal %= arraySize;
             }
             hashArray[hashVal] = item;
         }
         
         /**
          * 删除指定的元素
          * @param key 要删除的DataItem的值
          * @return 删除的元素,如果删除没有成功,则返回null
          */
         public DataItem delete(int key) {
             //计算哈希码
             int hashVal = this.hashFunc(key);
             
             //线性查找,直到找到空元素为止
             while (hashArray[hashVal] != null) {
                 //找到指定元素,将该元素存入一个临时变量等待返回,并把这个变量设为占位变量--nonItem
                 if (hashArray[hashVal].getKey() == key) {
                     DataItem temp = hashArray[hashVal];
                     hashArray[hashVal] = nonItem;
                     return temp;
                 }
                 //循环条件,哈希码++,并且如果到达尾端,从0开始
                 hashVal++;
                 hashVal %= arraySize;
             }
             //没有找到元素的情况,while退出,返回null
             return null;
         }
         
         /**
          * 查找某元素
          * @param key 要查找元素的值
          * @return 返回找到的元素DataItem类型,如果没有找到,则返回null
          */
         public DataItem find(int key) {
             //计算哈希码
             int hashVal = this.hashFunc(key);
             
             while (hashArray[hashVal] != null) {
                 if (hashArray[hashVal].getKey() == key)
                     return hashArray[hashVal];
                 //循环条件,哈希码++,并且如果到达尾端,从0开始
                 hashVal++;
                 hashVal %= arraySize;
             }
             return null;
         }
    }
        class HashTableApp
    {
    public static void main(String[] args) throws IOException
        {
        DataItem aDataItem;
        int aKey, size, n, keysPerCell;
                                      // get sizes
        System.out.print("Enter size of hash table: ");
        size = getInt();
        System.out.print("Enter initial number of items: ");
        n = getInt();
        keysPerCell = 10;
                                      // make table
        HashTable theHashTable = new HashTable(size);
           for(int j=0; j<n; j++)        // insert data
           {
           aKey = (int)(java.lang.Math.random() *
                                           keysPerCell * size);
           aDataItem = new DataItem(aKey);
           theHashTable.insert(aDataItem);
           }
           while(true)                   // interact with user
           {
           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(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
    ");
              } // end switch
           } // end while
        } // end main()
    //--------------------------------------------------------------
    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);
        }
    //--------------------------------------------------------------
    } // end class HashTableApp
    ////////////////////////////////////////////////////////////////
        再哈希化
        /**
    * 注意的是,表的容量是一个质数
    * 因为当再哈希化(二次探测也一样)的时候,探测位置达到数组最大值就得从头开始,这样做是为了防止陷入死循环
    * 例如:
    *     表的容量是15,步长为5,探测位置是0, 5, 10, 0, 5, 10....死循环
    *     表的容量是13(质数),步长为5,探测位置是0, 5, 10, 2, 7, 12, 4...会遍历每个位置
    * @author 星情
    *
    */
    class HashTable {
         private DataItem[] hashArray = null;
         private int arraySize = 0;
         private DataItem nonItem = null;
         
         public HashTable(int size) {
             this.arraySize = size;
             hashArray = new DataItem[arraySize];
             nonItem = new DataItem(-1);
         }
         
         public void displayTable() {
             System.out.print("Table: ");
             for (int i = 0; i < hashArray.length; i++) {
                 if (hashArray != null)
                     System.out.print(hashArray.getKey() + " ");
                 else
                     System.out.print("* ");
             }
             System.out.println();
         }
         
         public int hashFunc1(int key) {
             return key % arraySize;
         }
         
         public int hashFunc2(int key) {
             return 5 - key % 5;
         }
         
         public void insert(int key) {
             DataItem item = new DataItem(key);
             int hashVal = this.hashFunc1(key);
             int stepSize = this.hashFunc2(key);
             
             if (hashArray[hashVal] != null && hashArray[hashVal].getKey() != -1) {
                 hashVal += stepSize;
                 hashVal %= stepSize;
             }
             hashArray[hashVal] = item;
         }
         
         public DataItem delete(int key) {
             int hashVal = this.hashFunc1(key);
             int stepSize = this.hashFunc2(key);
             
             while (hashArray[hashVal] != null) {
                 if (hashArray[hashVal].getKey() == key) {
                     DataItem temp = hashArray[hashVal];
                     hashArray[hashVal] = nonItem;
                     return temp;
                 }
                 hashVal += stepSize;
                 hashVal %= stepSize;
             }
             return null;
         }
         
         public DataItem find(int key) {
             int hashVal = this.hashFunc1(key);
             int stepSize = this.hashFunc2(key);
             
             while (hashArray[hashVal] != null) {
                 if (hashArray[hashVal].getKey() == key)
                     return hashArray[hashVal];
                 hashVal += stepSize;
                 hashVal %= stepSize;
             }
             return null;
         }
    }
       

       
         
         
          
          

            
          

            
          
         
       

      


    源码下载:http://file.javaxxz.com/2014/10/29/235619234.zip
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|Java学习者论坛 ( 声明:本站资料整理自互联网,用于Java学习者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2024-5-18 20:34 , Processed in 0.390888 second(s), 46 queries .

    Powered by Discuz! X3.4

    © 2001-2017 Comsenz Inc.

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