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入门到精通教程
查看: 444|回复: 0

[算法学习]开散列的简单模拟:java实现(一)

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

    [LV.1]初来乍到

    发表于 2014-12-3 00:07:06 | 显示全部楼层 |阅读模式
    1. 散列

        散列有两种形式。一种是开散列(或外部散列),它将字典元素存放在一个潜无穷的空间里,因此它能处理任意大小的集合。
    另一种是闭散列(或内部散列), 它使用一个固定大小的存储空间,因此它能处理的集合的大小不能超过它的存储空间的大小。

    2. 开散列

        (1)下图是一个开散列表,它表示了开散列的基本数据结构。

          


        (2) 基本思想

            开散列的基本思想是将集合的元素(可能有无穷多个)划分成有穷多个类。例如,划分为0、1、2、....、B-1这B个类。用散列函数h将集合中的每个元素x映射到0、1、2、....、B-1之一,h(x)的值就是x所属的类。h(x)称为x的散列值。上面所说的每一个类称为一个桶,并且称x属于桶h(x).

            我们用一个链接表表示一个桶。x是将第i个链接表中的元素当且仅当h(x)=i,即x属于第i个桶。B个桶(链接表)的桶(表)头存放于桶(表)头数组中。


            用散列表来存储集合中的元素时,总希望将集合中的元素均匀地散列到每一个桶中,使得当集合中含有n个元素时,每个桶中平均有n/B个元素。如果我们能估计出n,并选择B与n差不多大小时,则每个桶中平均只有一两个元素。这样,字典的每个运算所需要的平均时间就是一个与n和B无关的小常数。由此可以看出,开散列表是将数组和链接表结合在一起的一种数据结构,并希望能利用它们各自的优点且克服它们各自的缺点。因此,如何选择随机的散列函数,使它能将集合中的元素均匀地散列到各个桶中是散列技术的一个关键。

       (3) 求余运算。

            如果x是不是数值型,将字符串x中的每个字符转换成一个整数,然后将字符串每个字符所对应的整数相加,用和除以B的余数作为h(x)的值,显然这个余数是0、1、2、....、B-1之一。

    3. 模拟代码:

    package boke.dictionary;
    /**
    * 开散列的简单模拟(一): 桶元素
    *
    * @since jdk1.6
    * @author 毛正吉
    * @version 1.0
    * @date 2010.05.25
    *
    */
    public class Node {
            public int iData;
            public Node next;
           
            public Node(int i) {
                    iData = i;
            }
    }
    -----------------------------------------------
    package boke.dictionary;
    /**
    * 开散列的简单模拟(一): 作为简单模拟,元素选取整型
    *
    * @since jdk1.6
    * @author 毛正吉
    * @version 1.0
    * @date 2010.05.25
    *
    */
    public class Hash {
            /**
             * @param args
             */
            public static void main(String[] args) {
                    Hash hh = new Hash(1000);
                    for (int i = 0; i <= 100; i++) {
                            hh.insert(i);
                    }
                    System.out.println(hh.find(10));
                    System.out.println(hh.find(50));
                    System.out.println(hh.find(90));
                    System.out.println(hh.find(1000));
                    hh.insert(1000);
                    System.out.println(hh.find(1000));
                    hh.delete(10);
                    System.out.println(hh.find(10));
                    hh.insert(0);
                    System.out.println(hh.find(0));
            }
            private Node[] bucket; // 桶
            private int maxSize; // 桶的个数
            /**
             * 构造方法
             *
             * @param maxSize
             */
            public Hash(int maxSize) {
                    this.maxSize = maxSize;
                    bucket = new Node[maxSize];
                    makeNULL();
            }
            /**
             * 字典初始化
             */
            public void makeNULL() {
                    for (int i = 0; i < maxSize - 1; i++) {
                            bucket = null;
                    }
            }
            /**
             * 查找x是否在字典中
             *
             * @param x
             * @return
             */
            public boolean find(int x) {
                    int mod = x % maxSize;
                    Node current = bucket[mod];
                    while (current != null) {
                            if (current.iData == x) {
                                    return true;
                            } else {
                                    current = current.next;
                            }
                    }
                    return false;
            }
            /**
             * 插入x到hash字典中
             *
             * @param x
             */
            public void insert(int x) {
                    if (!find(x)) {
                            Node node = new Node(x);
                            int mod = x % maxSize;
                            Node old = bucket[mod];
                            bucket[mod] = node;
                            bucket[mod].next = old;
                    } else {
                            System.out.println("该值已存在,不能重复插入!");
                    }
            }
            /**
             * 从hash字典中删除x
             *
             * @param x
             */
            public void delete(int x) {
                    int mod = x % maxSize;
                    if (bucket[mod] != null) {
                            if (bucket[mod].iData == x) {
                                    bucket[mod] = bucket[mod].next;
                            } else {
                                    Node current = bucket[mod];
                                    while (current.next != null) {
                                            if (current.next.iData == x) {
                                                    current.next = current.next.next;
                                            } else {
                                                    current = current.next;
                                            }
                                    }
                            }
                    }
            }
    }
    运行:[/code] C:java>java Hash
    true
    true
    true
    false
    true
    false
    该值已存在,不能重复插入!
    true

       
         
         
          
          

            
          

            
          
         
       

      


    源码下载:http://file.javaxxz.com/2014/12/2/000634296.zip
    回复

    使用道具 举报

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

    本版积分规则

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

    GMT+8, 2025-2-25 04:10 , Processed in 0.362170 second(s), 46 queries .

    Powered by Discuz! X3.4

    © 2001-2017 Comsenz Inc.

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