广告
返回顶部
首页 > 资讯 > 后端开发 > Python >Java数据结构之实现哈希表的分离链接法
  • 267
分享到

Java数据结构之实现哈希表的分离链接法

2024-04-02 19:04:59 267人浏览 薄情痞子

Python 官方文档:入门教程 => 点击学习

摘要

哈希表的分离链接法 原理 Hash Table可以看作是一种特殊的数组。他的原理基本上跟数组相同,给他一个数据,经过自己设置的哈希函数变换得到一个位置,并在这个位置当中放置该数据。哦

哈希表的分离链接法

原理

Hash Table可以看作是一种特殊的数组。他的原理基本上跟数组相同,给他一个数据,经过自己设置的哈希函数变换得到一个位置,并在这个位置当中放置该数据。哦对了,他还有个名字叫散列

0 1
数据1 数据2

就像这个数组,0号位置放着数据1,1号位置放数据2
而我们的哈希表则是通过一个函数f(x) 把数据1变成0,把数据2变成1,然后在得到位置插入数据1和数据2。
非常重要的是哈希表的长度为素数最好!!
而且当插入数据大于一半的时候我们要进行扩充!!!

冲突问题产生

现在这个表就是2个数据,所以不会产生什么冲突,但是若一个数据他通过f(x)计算得到的位置也是0呢?是不是就跟数据1产生了冲突,因为数据1已经占据了这个位置,你无法进行插入操作。对不对。

所以我们该如何解决这个问题呢,诶,我们肯定是想两个都可以插入是不是,就像一个炸串一样把他串起来。如图

在这里插入图片描述

a b c就像一个炸串,而如何实现这个炸串就有多种方式。这里我们用线性表来实现

线性表实现

我们可以用java自带的List ArrayList等表,这边也给出单链表的实现方式。


public class MyArray<AnyType> {

我们首先得创建一个内部类用来存放数据,以及保存下个节点


 class Arraynode<AnyType>{
     public AnyType data;
     public ArrayNode<AnyType> next;
     public ArrayNode(AnyType data){this(data,null);}
     private ArrayNode(AnyType data,ArrayNode<AnyType> next){
         this.data=data;
         this.next=next;
     }
 }//save type node;

设置我们这个线性表所需要的对象,例如size和一个头节点,以及我们要进行初始化,判断这个表是否为空等。


 private int theSize;//array list size
 private ArrayNode<AnyType> head; //head node every data behind it
 //init MyArray
 public MyArray(){doClear();}
 public void clear(){doClear();}
 private void doClear(){
     theSize=0;
     head=new ArrayNode<>(null);
 }
 //get size and is empty
 public int size(){return theSize;}
 public boolean isEmpty(){return theSize==0;}

接下来我们需要实现他的基本操作,是否包含,插入,获得以及删除。


   //contain
   public boolean contains(AnyType x){
       ArrayNode<AnyType> newNode=head;//get a new node=head
       while (newNode.next!=null) {
           newNode=newNode.next;
           if (newNode.data == x)
               return true;
       }
       return false;
   }
   //get the data in idx from array
   public AnyType get(int idx){return get(idx,head).data;}
   private ArrayNode<AnyType> get(int idx,ArrayNode<AnyType> node){
       if(idx<0||idx>size())
           throw new IndexOutOfBoundsException();//out of length
       ArrayNode<AnyType> newNode=node;
       //find start head.next
       for (int i = 0; i < idx; i++)
           newNode=newNode.next;
       return newNode;
   }
   //set data into array
   public void set(AnyType x){set(x,head);}
   private void set(AnyType x,ArrayNode<AnyType> node){
       ArrayNode<AnyType> newNode=node;
       while (newNode.next!=null)
           newNode=newNode.next;
       theSize++;
       newNode.next=new ArrayNode<>(x);
   }
    //remove
   public void remove(AnyType x){remove(x,head);}
   private void remove(AnyType x,ArrayNode<AnyType> node){
       if(!contains(x))
           return;
       while (node.next!=null){
           node=node.next;
           if (node.next.data==x)
               break;
       }
       ArrayNode<AnyType> oldNode=node.next;
       node.next=null;
       node.next=oldNode.next;
   }
}

哈希表实现


public class MyHashTable<AnyType>{
    //define the things that we need to use
    private static final int DEFAULT_SIZE = 10;
    private MyArray<AnyType>[] arrays;
    private int currentSize;

因为我实现的是学号的存储
也就是带0开头的数据 所以我用字符串
这里这个myHash就是我实现的简单哈希函数,即获得的数据字符串化,得到最后两个字符


    private int myHash(AnyType x){
        String s=x.toString();
        return Integer.parseInt(s.substring(s.length()-2,s.length()));
    }

初始化哈希表,设置的默认大小为10,然后进行素数判断,如果它不是素数,那么就找到他的下一个素数作为表的大小。


    //init we should ensure that the table size is prime
    public MyHashTable(){
        ensureTable(nextPrime(DEFAULT_SIZE));
        makeEmpty();
    }
    private void ensureTable(int x){
        arrays=new MyArray[x];
        for (int i = 0; i < arrays.length; i++)
            arrays[i]=new MyArray<>();
    }
    //make the array empty
    public void makeEmpty(){
        currentSize=0;
        for(MyArray<AnyType> myArray:arrays)
            myArray.clear();
    }
    //size and empty
    public int size(){return currentSize;}
    public boolean isEmpty(){return currentSize==0;}

基本方法的实现,插入,获得,删除,包含


    //contain x
    public boolean contains(AnyType x){
        int position=myHash(x);
        return arrays[position].contains(x);
    }
    //insert x
    public void insert(AnyType x){
        int position=myHash(x);
        if(arrays[position].contains(x))
            return;
        else if(arrays[position].size()==0)
                if(++currentSize>arrays.length)
                    makeBigger();
        arrays[position].set(x);

    }
    //get idx data
    public MyArray<AnyType> get(int idx){ return arrays[idx];}

在这里,如果插入的时候啦,实际的currentSize大于二分之一表的大小了
则进行扩充表
一般扩充表的话,我们是直接两倍两倍扩充的。


    //makeBigger
    public void makeBigger() {
        MyArray[] oldArray = arrays;
        arrays = new MyArray[2 * arrays.length];
        for (int i = 0; i < oldArray.length; i++)
            arrays[i] = oldArray[i];
    }

下一个素数查找,如果他是偶数,则给他加1这样可以大大减少开销。
然后进行下一个素数判断,奇数当中找素数。


    //nextPrime
    private int nextPrime(int i){
        if(i%2==0)
            i++;
        for (; !isPrime(i); i+=2);//ensure i is jishu
        return i;
    }

是否为素数判断,如果为2则范围true
如果是1或者为偶数则返回false
都不满足则从三开始,他的平方小于输入的数,用奇数进行操作,因为用偶数的话,前面那个2就直接判断了,所以我们用奇数,大大减少开销。
我们也可以设置他的判断条件是小于输入的二分之一,但是我们用平方进行判断大大减少了开销,而且对于奇数来说是十分有效果的。


    //is Prime
    private boolean isPrime(int i){
        if(i==2||i==3)
            return true;
        if(i==1||i%2==0)
            return false;
        for (int j = 3; j*j<=i ; j+=2)
            if (i%j==0)
                return false;
        return true;
    }
}

测试


public class test {
    public static void main(String[] args) {
        MyHashTable<String> a=new MyHashTable<>();
        a.insert("001");
        a.insert("01");
        for(int i=1;i<a.get(1).size()+1;i++){
            System.out.println(a.get(1).get(i));
        }
    }
}

结果

在这里插入图片描述

到此这篇关于Java数据结构之实现哈希表的分离链接法的文章就介绍到这了,更多相关Java哈希表的分离链接法内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: Java数据结构之实现哈希表的分离链接法

本文链接: https://www.lsjlt.com/news/129508.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • Java数据结构之实现哈希表的分离链接法
    哈希表的分离链接法 原理 Hash Table可以看作是一种特殊的数组。他的原理基本上跟数组相同,给他一个数据,经过自己设置的哈希函数变换得到一个位置,并在这个位置当中放置该数据。哦...
    99+
    2022-11-12
  • Java数据结构中实现哈希表的分离链接法
    这篇文章主要介绍“Java数据结构中实现哈希表的分离链接法”,在日常操作中,相信很多人在Java数据结构中实现哈希表的分离链接法问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Java数据结构中实现哈希表的分离...
    99+
    2023-06-20
  • C++数据结构之哈希表的实现
    目录哈希表概念散列函数直接定址法除留余数法平方取中法哈希冲突线性探测二次探测链地址法哈希表的实现闭散列开散列哈希表概念 二叉搜索树具有对数时间的表现,但这样的表现建立在一个假设上:输...
    99+
    2023-03-11
    C++数据结构 哈希表 C++哈希表 C++数据结构
  • 数据结构Typescript之哈希表实现详解
    目录哈希表的结构特点面向对象方法封装哈希表哈希冲突构造函数基本单元:键值对主体:哈希表增加键值对获取键值删除键值对哈希表的结构特点 相比链表繁杂的遍历处理,哈希表的作用是存储无固定...
    99+
    2023-01-30
    Typescript数据结构哈希表 Typescript数据结构
  • C++数据结构之哈希表如何实现
    本篇内容主要讲解“C++数据结构之哈希表如何实现”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“C++数据结构之哈希表如何实现”吧!哈希表概念二叉搜索树具有对数时间的表现,但这样的表现建立在一个假...
    99+
    2023-07-05
  • 带你了解Java数据结构和算法之哈希表
    目录1、哈希函数的引入①、把数字相加②、幂的连乘2、冲突3、开放地址法①、线性探测②、装填因子③、二次探测④、再哈希法4、链地址法5、桶6、总结1、哈希函数的引入 大家都用过字典,字...
    99+
    2022-11-13
  • Java数据结构与算法系列精讲之哈希算法实现
    概述 从今天开始, 小白我将带大家开启 Java 数据结构 & 算法的新篇章. 获取哈希值 hashCode()方法可以返回一个对象的哈希值. 需要注意的是, 我们需要对值...
    99+
    2022-11-13
  • Java数据结构之双向链表的实现
    目录1 双向链表1.1 双向链表介绍1.2 双向链表实现思路2 双向链表实现完整代码2.1 节点类 Student.java2.2 双向链表实现类 StudentDoubleLink...
    99+
    2022-11-13
    Java 数据结构 双向链表 Java 双向链表
  • Java实现链表数据结构的方法
    什么是链表? 链表是一种物理存储单元上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针连接次序实现的。每一个链表都包含多个节点,节点又包含两个部分,一个是数据域(储存节...
    99+
    2022-11-12
  • Java数据结构之链表的示例分析
    小编给大家分享一下Java数据结构之链表的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!一、链表的介绍什么是链表链表是一种物理存储单元上非连续、非顺序的存...
    99+
    2023-06-15
  • Java数据结构之LinkedList从链表到实现
    目录1.ArrayList的缺陷2.LinkedListLinkedList概念LinkedList的使用3.链表的概念及结构4.ArrayList和LinkedList的区别1.A...
    99+
    2023-05-18
    Java LinkedList Java 链表
  • Java数据结构和算法之链表的示例分析
    这篇文章主要介绍Java数据结构和算法之链表的示例分析,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!1、链表(Linked List)链表通常由一连串节点组成,每个节点包含任意的实例数据(data fiel...
    99+
    2023-06-28
  • Java数据结构之实现哈夫曼树的示例分析
    这篇文章主要介绍了Java数据结构之实现哈夫曼树的示例分析,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。一、与哈夫曼树相关的概念概念含义1. 路径从树中一个结点到另一个结点的...
    99+
    2023-06-15
  • Java数据结构之双向链表如何实现
    这篇文章主要讲解了“Java数据结构之双向链表如何实现”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Java数据结构之双向链表如何实现”吧!双向链表(Doubly linked list)什...
    99+
    2023-06-30
  • C++数据结构之单链表的实现
    目录一、单链表的定义二、单链表的基本操作的实现1.初始化2.取值3.查找4.插入5.删除三、完整代码四、测试一下代码一、单链表的定义 线性表的链式存储又称为单链表,它是指通过一组任意...
    99+
    2022-11-13
  • Java数据结构之链表实现(单向、双向链表及链表反转)
    前言 之前学习的顺序表查询非常快,时间复杂度为O(1),但是增删改效率非常低,因为每一次增删改都会元素的移动。可以使用另一种存储方式-链式存储结构。 链表是一种物理存储单元上非连续、...
    99+
    2022-11-12
  • Java数据结构之双端链表原理与实现方法
    本文实例讲述了Java数据结构之双端链表原理与实现方法。分享给大家供大家参考,具体如下:一、概述:什么时双端链表:链表中保持这对最后一个连点引用的链表从头部插入要对链表进行判断,如果为空则设置尾节点为新添加的节点从尾部进行插入如果链表为空,...
    99+
    2023-05-30
    java 数据结构 双端链表
  • java数据结构中单链表与双向链表的实现方法
    这篇文章主要介绍“java数据结构中单链表与双向链表的实现方法”,在日常操作中,相信很多人在java数据结构中单链表与双向链表的实现方法问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”java数据结构中单链表与...
    99+
    2023-06-20
  • C语言数据结构之单链表的实现
    目录一.为什么使用链表二.链表的概念三.链表的实现3.1 创建链表前须知3.2 定义结构体3.3 申请一个节点3.4 链表的头插3.5 链表的尾插3.6 链表的尾删3.7 链表的头删...
    99+
    2022-11-13
  • Java链表数据结构及使用方法实例分析
    本篇内容主要讲解“Java链表数据结构及使用方法实例分析”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Java链表数据结构及使用方法实例分析”吧!认识链表结构单向链表单链表在内存中的表示:可以看...
    99+
    2023-07-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作