数据结构-----哈希表

哈希表概念

哈希表(Hash table,也叫哈希表),是根据关键码值(Key value)而直接进行访问的数据结构。也就是说,它通过把关键码散值映射到表中一个位置来访问记录,以加快查找的速度。这个映射函数叫做散列函数存放记录的数组叫做散列表

在这里插入图片描述
Java程序在访问数据库时候如果频繁的访问数据库,但是有的数据不用每次都查询数据库,这里可以采用缓存解决这个问题。

  1. 利用缓存的产品:Redis,Memcache
  2. 自己写一个哈希表(数组+链表,数组+二叉树)
    在这里插入图片描述

哈希表的实现思路

在这里插入图片描述
由图可知:哈希表的实现需要三个类:

//哈希表
class HashTab  {
    linkedList [] 
    LinkedListArr
 //add
 //list
//find
//del
//散列函数 绝对id 对应到哪个链表
}

//链表
class  LinkedList {
   Node head = null; //头指针,
   指向当前链表的第一个雇员
  //相关对雇员的操作
 //add
 //list
//find
//del
}

//数据节点
class Node{
 id;
 name;
 address;
}
代码的实现

思路在代码的备注里面

public class HashtableDemo {
    public static void main(String[] args) {
        //穿件哈希表
        Hashtab hash=new Hashtab(8);
        Node node1=new Node(1,"zhangsan");
        Node node2=new Node(2,"zhang");
        Node node3=new Node(3,"san");
        Node node4=new Node(4,"1234");
        hash.add(node1);
        hash.add(node2);
        hash.add(node3);
        hash.add(node4);
        hash.print();
        hash.findNodeById(3);
    }


}

//Node节点
class Node{
    public int id;
    public String name;
    public Node next;//默认为null

    public Node(int id, String name) {
        super();
        this.id = id;
        this.name = name;
    }
}

//创建哈希表
class Hashtab{
    private LinkedList[] LinkedListArray;
    private int size;
    //构造器
    public Hashtab(int size){
        this.size=size;
        //初始化LinkedListArray
        LinkedListArray =new LinkedList[size];
        //坑!!!! 这是要分别初始化每一个链表
        for (int i = 0; i <size ; i++) {
            LinkedListArray[i]=new LinkedList();
        }
    }

    //添加雇员
    public void add(Node node){
        //根据原的id得到,应该添加到那一条链表
        int linkedListNo=hashFun(node.id);
        //把node节点添加到对应的链表中,
        LinkedListArray[linkedListNo].add(node);

        
    }

    //遍历所有的链表,遍历HashTable
    public void print(){
        for (int i = 0; i <size ; i++) {//遍历哈希表的每一个链表
            LinkedListArray[i].print(i);
        }
    }


    //编写散列函数,使用简单的取模方法
    public int hashFun(int id){
        return id%size;//取模
    }

    //根据id查找节点
    public void findNodeById(int id){
        //使用哈希散列确定到哪个链表下查找该节点
        int num=hashFun(id);
        //在链表中查找
        Node node =LinkedListArray[num].findNodeById(id);
        if(node!=null){
            System.out.printf("在%d条链表找到了Node id=%d",(num+1),id);
        }else {
            System.out.println("没有找到");
        }
    }
}



//创建一个LinkedList,表示链表
class LinkedList{
    //头指针,指向第一个Node,因此这个head指向第一个第一个Node节点
    private Node head;//默认为null

    /*
    添加Node到链表
    说明:
    1.假设:添加雇员时,id是自增长的,即id的分配是从小到大的
    所以我们直接把Node接天添加到链表最后就行
     */
    public void add(Node node ){
        //如果是第一个Node,直接加入链表就行
        if(head==null){
            head=node;
            return;
        }
        //不是第一个node,则需要一个辅助的节点,遍历到链表的租后
        Node cur=head;
        while(true){
            if(cur.next==null){//说明到达链表的休后一个节点
                break;
            }
            //把当前接地那继续向后移动
            cur=cur.next;
        }
        //退出时直接把node节点加入到链表
        cur.next=node;
    }

    //遍历链表
    public void print(int no ){
        if(head==null){
            System.out.println("第"+no+"链表为null");
            return;
        }

        System.out.print ("第"+no+"链表信息为");
        Node cur=head;//辅助指针
        while(true){
            System.out.printf("=> id=%d name=%s\t",cur.id,cur.name);
            if(cur.next==null){//说明为最后一个节点
                break;
            }
            cur=cur.next;//遍历喜爱个节点
        }
        System.out.println();
    }

    //根据id查找雇员
    public Node  findNodeById(int id){
        //判断链表是否为空
        if(head==null){
            System.out.println("链表为null");
            return null;
        }
        //不为空,借助辅助指针查找
        Node cur=head;
        while(true){
            if(cur.id==id){
                break;//此时的cur就会要找的节点
            }
            //退出
            if(cur.next==null){//说明遍历完当前节点没有找到该节点
                cur=null;
            }
            cur=cur.next;//向后移动找节点
        }
        return cur;
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值