【编程习作】实现Hash表

简介: 作者:gnuhpc 出处:http://www.cnblogs.com/gnuhpc/ class Node{//节点数据结构     private Object value;//节点的值     private Node next;//链表中指向下一结点的引用 ...

作者:gnuhpc
出处:http://www.cnblogs.com/gnuhpc/

class Node{//节点数据结构
    private Object value;//节点的值
    private Node next;//链表中指向下一结点的引用
    /*提供了常见的操作*/
    public Node(Object value){this.value = value;};
    public Object getValue() {return value;}
    public Node getNext() {return next;}
    public void setNext(Node next){this.next=next;}
}

public class MyHashSet {//Hash数据结构
    private Node[] array;//存储数据链表的数组
    private int size = 0;//表示集合中存放的对象的数目
    public MyHashSet(int length){
        array = new Node[length];//创建数组
    }
    public int size(){return size;}
    private static int hash (Object o){    //根据对象的哈希码得到一个优化的哈希码,
                                        //算法参照java.util.HashMap的hash()方法
        int h = o.hashCode();
        h += ~(h<<9);
        h ^= (h>>>14);
        h += (h<<4);
        h ^= (h>>>10);
        return h;
    }
    private int indexFor(int hashCode){    //根据Hash码得到其索引位置
                                        //算法参照java.util.HashMap的indexFor()方法
        return hashCode & (array.length-1);
    }
    public void add(Object value) {//把对象加入集合,不允许加入重复的元素
        int index = indexFor(hash(value));//先根据value得到index
        System.out.println("index:" + index + " value:" + value);
        Node newNode = new Node(value);//由value创建一个新节点newNode
        Node node = array[index];//由index得到一个节点node
        if (node == null) {//若这个由index得到的节点是空,则将新节点放入其中
            array[index]=newNode;
            size++;
        } else {//若不为空则遍历这个点上的链表(下一个节点要等于空或者该节点不等于新节点的值--不允许重复)
            Node nextNode;
            while (!node.getValue().equals(value) && (nextNode = node.getNext())!=null) {
                node = nextNode;
            }
            if (!node.getValue().equals(value)) {//若值不相等则加入新节点
                node.setNext(newNode);
                size++;
            }
        }
    }
    public boolean contains(Object value){
        int index = indexFor(hash(value));
        Node node = array[index];
        while (node!=null && !node.getValue().equals(value)) {
            node = node.getNext();
        }//横向查找
        if (node!=null && node.getValue().equals(value)) {
            return true;
        } else {
            return false;
        }
    }
    public boolean remove(Object value) {
        int index = indexFor(hash(value));
        Node node = array[index];
        if (node!=null && node.getValue().equals(value)) {//若是第一个节点就是要remove的
            array[index]=node.getNext();
            size--;
            return true;
        }
        Node lastNode = null;
        while (node!=null && !node.getValue().equals(value)) {//若不是第一个节点就横向查找
            lastNode = node;//记录上一个节点
            node = node.getNext();
        }
        if (node!=null && node.getValue().equals(value)) {
            lastNode.setNext(node.getNext());
            size--;
            return true;
        }else {
            return false;
        }
    }
    public Object[] getAll() {
        Object [] values = new Object[size];
        int index = 0;
        for (int i = 0; i < array.length; i++) {
            Node node = array[i];
            while (node!=null) {
                values[index++]=node.getValue();
                node = node.getNext();
            }   
        }
        return values;   
    }
    public static void main(String[] args) {
        MyHashSet set = new MyHashSet(6);
        Object [] values = {"Tom","Mike","Mike","Jack","Mary","Linda","Rose","Jone"};
        for (int i = 0; i < values.length; i++) {
            set.add(values[i]);
        }
        set.remove("Mary");
        System.out.println("size="+set.size());
        values = set.getAll();
        for (int i = 0; i < values.length; i++) {
            System.out.println(values[i]);
        }
        System.out.println(set.contains("Jack"));
        System.out.println(set.contains("Linda"));
        System.out.println(set.contains("Jane"));
    }
}

 

附:Java中的Hash结构有HashSet和HashMap,哈希表中的每个位置称为桶(bucket),当发生哈希冲突时就以链表形式存放多个元素。

这两个数据结构中有如下属性:

容量:桶的数量,例子中是6.

初始容量:创建时桶的个数。

大小:元素的数目。

负载因子(Load factor):size/capacity,小的冲突少,这两个类可以指定负载因子。当哈希表的负载达到用户设定的负载因子时会自动成倍增加容量,并且重新分配元素位置。默认为0.75,兼顾时间和空间开销。

 

 

作者:gnuhpc
出处:http://www.cnblogs.com/gnuhpc/


               作者:gnuhpc
               出处:http://www.cnblogs.com/gnuhpc/
               除非另有声明,本网站采用知识共享“署名 2.5 中国大陆”许可协议授权。


分享到:

目录
相关文章
|
网络安全
kali 启用默认root,开启SSH服务,安装VNC,设置服务自启动
启用默认root,开启SSH服务,设置服务自启动,安装VNC
|
Python 数据挖掘 自然语言处理
Python---qq群聊天记录词云分析
python拥有近13w个第三方库,其中有很多优秀的库,比如wordcloud,scipy,jieba等库,能快速实现很多功能,比如制作一个QQ群聊天记录词云…… 工具:PyCharm, Python3.6.5 1.获取数据源 qq左下角 导出消息记录 要用.txt导出到任意盘符,接下来就要对导出的txt文件进行数据分析。
2841 0
|
6月前
|
弹性计算
【已解决】Matomo本地SMTP配置可以发邮件,但部署到阿里云ECS就发不了邮件
在阿里云ECS上使用Matomo和PHPMailer发送邮件时遇到问题,邮件无法发出且接口调用Pending。经过排查,发现是ECS安全组未开放25/465端口,导致SMTP请求无法正常通信。解决方法为在安全组中配置并开放25/465端口,从而恢复邮件发送功能。
108 2
|
10月前
|
存储 缓存 大数据
ClickHouse核心概念详解:表引擎与数据模型
【10月更文挑战第26天】在大数据时代,数据处理的速度和效率变得至关重要。ClickHouse,作为一个列式存储数据库系统,以其高效的查询性能和强大的数据处理能力而受到广泛欢迎。本文将从我个人的角度出发,详细介绍ClickHouse的核心概念,特别是其表引擎和数据模型,以及这些特性如何影响数据的存储和查询。
369 1
|
存储 关系型数据库 MySQL
MySQL基础命令及使用示例
这些基础命令构成了与MySQL数据库交互的核心,理解并掌握它们对于进行有效的数据库操作至关重要。在实际使用中,建议结合实际案例和需求来练习这些命令,以加深理解和提高效率。
276 3
|
机器学习/深度学习 Kubernetes 算法框架/工具
ONNX 与容器化:实现端到端的 ML 管道自动化
【8月更文第27天】在现代机器学习 (ML) 工作流程中,模型的训练、转换、部署和管理通常涉及多个步骤和技术栈。Open Neural Network Exchange (ONNX) 提供了一种统一的方式来表示和交换机器学习模型,而容器化技术(如 Docker 和 Kubernetes)则为部署和管理这些模型提供了灵活且可扩展的方式。本文将探讨如何结合 ONNX 和容器化技术来构建端到端的 ML 管道自动化系统。
293 1
|
芯片 UED 内存技术
全球 25 大高科技城市排名出炉:北上深上榜,但国内最牛的却是它?
随着城市化进程的加快,根据相关机构的估算,未来大部分人都会居住在城市中。和乡村相比,城市的优势在于更为完善的基础设施、商业圈,当然也包括科技方面。 近日,美国媒体 Business Insider 根据一些研究数据,在网站上放出一个全球 25 大高科技城市排名。其中,上榜的美国城市有 6 个、中国有 5 个、日韩印度各有一个,其他上榜的城市基本为加拿大和欧洲地区。
1905 0
全球 25 大高科技城市排名出炉:北上深上榜,但国内最牛的却是它?
|
开发工具 git Shell
在git命令行下查看git stash里面文件的内容
终于建了一个自己个人小站:https://huangtianyu.gitee.io,以后优先更新小站博客,欢迎进站,O(∩_∩)O~~ 在使用git的时候往往会保存一些东西,在保存的时候使用的就是git stash,强大的git使得保存修改和恢复修改变的很容易,但有时候时间久了不记得stash里面的内容是什么了,通过在stackflow里面查找,找到了一个好的方法。
7500 0
|
Web App开发 XML Java
通过freemarker生成一个word,解决生成的word用wps打开有问题的问题,解决出word时中文文件名乱码问题,解决打开出word时打开的word出现问题的问题,出图片,解决动态列表
 通过freemarker制作word比较简单 步骤:制作word模板。制作方式是:将模板word保存成为xml----在xml的word模板中添加相应的标记----将xml的word文件的后缀名改成ftl文件(要注意的是生成xml格式要是2003格式的xml,也就是说拿到的word模板得是2003格式的,否则用wps打开word将会出现问题)   详细步骤如下: 模板制作(将要动态显示的
4818 0
|
Web App开发 域名解析 监控
前端可观测性的宣讲-1022
前端可观测性的宣讲-1022
569 0
前端可观测性的宣讲-1022

热门文章

最新文章