哈希表思路

emp.java

package day16.hash;
//雇员
public class emp {
    public int id;
    public  String name;
    public emp next;

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

}

emplinklist.java

package day16.hash;


public class emplinklist {
//    链表
    private emp head;


//   添加雇员
//    1.假定 ;当添加雇员时id是自增,id分配从小到大。
//    将该雇员直接添加到本链表的最后即可。

    public void add(emp emp){
       if (head==null){   //空,直接添加
           head=emp;
           return;
       }
        emp curemp =head;   //临时变量
       while (true){        //判断要加入的链表的下一位是否为空,不为空则后移,为空则直接添加。
           if (curemp.next==null){
               break; //跳出while
           }
           curemp =curemp.next;//后移

       }
//        退出时将emp加到链表
        curemp.next=emp;
    }
    //遍历链表
    public void list(int no){
        if (head==null){

            System.out.println(no+"号链表为空");
        return;
        }
        System.out.print(no+"号链表的信息为");
        emp curemp=head;
        while (true){
            System.out.printf("id=%d name=%s",curemp.id,curemp.name);
            if (curemp.next==null){ //说明已经是最后节点
                break;
            }
            curemp=curemp.next;
        }
        System.out.println();
    }

//   根据id查找name.
    public emp findbyid(int id){
//        判断是否为空
        if (head==null){
            System.out.println("链表为空");
            return null;
        }
        emp curemp =head;//临时变量
        while (true){
            if (curemp.id == id){//找到
               break;
            }
            if (curemp.next==null){
//           说明已经遍历完成,并且没有找到
                curemp=null;
            }
        curemp=curemp.next;//把指针向后移动。
        }//跳出来之后
        return curemp;
    }

}


//bug:如果链表为空,查找没有的值不会出错,但是如果链表不为空,查找没有的值则会报错。

hashtab.java

package day16.hash;

//思考:在hashtab类中,完成的是对emp的添加,在emplinklist中,编写了针对链表添加的方法。

public class hashtab {
//  说明:  一个hashtab是一个数组,里面包含了多条链表.
//    写了一个构造器,初始化hashtab的时候,要初始化每一个链表


//    管理多条链表
    private emplinklist[]  emplinklists;//数组放的是链表;
private int size; //链表的条数
//    构造器
    public hashtab(int size){
        this.size=size;
//        初始化emplinklistarray
        emplinklists = new emplinklist[size];//这里创建了一个大小为size的数组,类型为emplinklist
        for (int i=0;i<size;i++){
            emplinklists[i]=new emplinklist();//给每一个链表初始化
        }
    }
//    添加雇员
    public void add(emp emp){
        //根据员工的id得到该员工应该添加到那条链表。得到一个no存放在emplinkedlistNO中。
int emplinkedlistNO =hashfun(emp.id);
//将emp添加到对应的链表
        emplinklists[emplinkedlistNO].add(emp); //数组的add方法。
    }

    public void list(){
        for (int i=0;i<size;i++){
            emplinklists[i].list(i);
        }
    }
    public void findbyid(int id){
        int i = hashfun(id);//散列函数判断哪个链表查找
        emp emp = emplinklists[i].findbyid(id);
        if (emp!=null){
            System.out.println("在"+i+"链表找到了"+emp.name);
        }else {
            System.out.println("没有找到改雇员");
        }
    }


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

}

test.java

package day16.hash;

import java.util.Scanner;

public class test {
    public static void main(String[] args) {
        hashtab hashtab = new hashtab(7);
//       写一个菜单
        String key ="";
        while (true){
            System.out.println("add: 添加");
            System.out.println("list: 显示");
            System.out.println("exit: 退出");
            System.out.println("find: 查找");
            key = new Scanner(System.in).next();
            switch (key){
                case "add":
                    System.out.println("请输入id");
                    int id = new Scanner(System.in).nextInt();
                    System.out.println("请输入名字");
                    String name =new Scanner(System.in).next();
                    emp emp = new emp(id,name);
                    hashtab.add(emp);
                    break;
                case "list":
                    hashtab.list();
                    break;
                case "find":
                    System.out.println("请输入id");
                     id =new Scanner(System.in).nextInt();
                    hashtab.findbyid(id);
                    break;
                case "exit":
                    System.exit(0);
                    break;
            }
        }
    }
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
哈希表是一种基于哈希函数进行快速查找的数据结构,它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度。哈希表的设计思路如下: 1. 哈希函数的设计:哈希函数是哈希表的核心,它将关键字映射到哈希表中的位置。一个好的哈希函数应该具有以下特点: - 映射范围广:哈希函数应该将关键字均匀地映射到哈希表中的位置,避免出现大量的哈希冲突。 - 计算速度快:哈希函数的计算速度应该尽可能快,以提高哈希表的访问速度。 - 低冲突率:哈希函数应该尽可能地避免哈希冲突,以提高哈希表的访问效率。 2. 哈希冲突的解决:由于哈希函数的映射范围是有限的,所以不同的关键字可能会映射到同一个位置,这就是哈希冲突。哈希冲突的解决方法有以下两种: - 链地址法:将哈希表中的每个位置都连接一个链表,当发生哈希冲突时,将新的关键字插入到链表的末尾。 - 开放地址法:当发生哈希冲突时,通过某种算法找到哈希表中的下一个空位置,将新的关键字插入到该位置。 3. 哈希表的增删查改操作:哈希表的增删查改操作都需要先通过哈希函数找到关键字在哈希表中的位置,然后再进行相应的操作。具体操作如下: - 插入操作:将新的关键字插入到哈希表中的对应位置,如果发生哈希冲突,则按照链地址法或开放地址法进行解决。 - 删除操作:将关键字从哈希表中对应位置删除,如果该位置上有链表,则需要遍历链表找到对应的关键字进行删除。 - 查找操作:通过哈希函数找到关键字在哈希表中的位置,如果该位置上有链表,则需要遍历链表找到对应的关键字进行查找。 - 修改操作:通过哈希函数找到关键字在哈希表中的位置,如果该位置上有链表,则需要遍历链表找到对应的关键字进行修改。 下面是一个使用链地址法实现的哈希表的Python代码示例: ```python class ListNode: def __init__(self, key=None, value=None): self.key = key self.value = value self.next = None class MyHashMap: def __init__(self): self.size = 1000 self.table = [None] * self.size def _hash(self, key): return key % self.size def put(self, key, value): index = self._hash(key) if not self.table[index]: self.table[index] = ListNode(key, value) else: node = self.table[index] while node: if node.key == key: node.value = value return if not node.next: break node = node.next node.next = ListNode(key, value) def get(self, key): index = self._hash(key) node = self.table[index] while node: if node.key == key: return node.value node = node.next return -1 def remove(self, key): index = self._hash(key) node = prev = self.table[index] if not node: return if node.key == key: self.table[index] = node.next else: node = node.next while node: if node.key == key: prev.next = node.next break node, prev = node.next, prev.next ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值