哈希表的分析与代码实现

哈希表的结构

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

代码实现

从哈希表中可以看出需要三个结构来共同管理哈希表

  1. 节点,用来记录节点信息
  2. 链表,用来管理节点的信息
  3. 数组,用来管理链表的信息

节点(存储信息)

//管理每一个员工的信息
class Emp {
    public int no;
    public String name;
    public String nickname;
    public Emp next;

    public Emp(int no, String name, String nickname) {
        this.no = no;
        this.name = name;
        this.nickname = nickname;
    }

    @Override
    public String toString() {
        return "员工{" +
                "编号为=" + no +
                ", 姓名为='" + name + '\'' +
                ",昵称='" + nickname + '\'' +
                '}';
    }
}

单向链表(用来管理节点信息)

分别设置增删改查的方法,来管理节点

//创建链表来管理员工的信息
class SingleList{
//要有节点的属性信息
    public Emp head;
    //增加节点
    public void add(Emp newEmp){
        if(head==null){
            head=newEmp;
            System.out.println("新员工"+newEmp.name+"添加成功!");
            return;
        }
        Emp temp=head;
        while(true){
            if(temp.next==null){
                temp.next=newEmp;
                System.out.println("新员工"+newEmp.name+"添加成功!");
                break;
            }else {
                temp=temp.next;
            }
        }
    }
    //按照大小顺序添加节点
    public void addByOrder(Emp newEmp){
        if(head==null){
            head=newEmp;
            System.out.print("新员工"+newEmp.name+"添加成功!");
            return;
        }else if (head.next==null){
            if(head.no>newEmp.no){
                Emp No0=head;
                head=newEmp;
                newEmp.next=No0;
                return;
            }
        }else {
            //还是要引入辅助变量
            Emp temp = head;
            //此标记用来判断所添加的元素是否已经存在
            boolean flag = false;
            //遍历整个链表
            while (true) {
                if (temp.next == null) {
                    break;
                }
                if (temp.next.no > newEmp.no) {
                    break;
                } else if (temp.next.no == newEmp.no) {
                    flag = true;
                    break;
                }
                temp = temp.next;
            }

            if (flag) {
                System.out.println("准备插入的人编号【" + temp.no + "】已存在");
            } else {
                //若可以插入,则将新的节点插入
                newEmp.next = temp.next;
                temp.next = newEmp;
                System.out.print("新员工"+newEmp.name+"添加成功!");
            }
        }

    }
    //删除节点,假设节点一定存在
    public void delete(int no){

        if(head.no==no&&head.next!=null){
            head=head.next;
            return;
        }
        if (head.no==no&&head.next==null){
            head=null;
            return;
        }
        Emp temp=head;
        boolean flag=false;
        while (true){
            //说明是一个空的链表
            if(temp==null){
                break;
            }

            if(temp.next.no==no){
                //说明找到了
                flag=true;
                break;
            }
            temp=temp.next;
        }
        if(flag){
            temp.next=temp.next.next;
            System.out.println("编号为【"+no+"】的员工删除成功!");
        }else {
            System.out.println("编号为【"+no+"】的员工不存在!");
        }
    }
    //显示节点
    public void displayAll(){
        if(head==null){
            System.out.println("该链表为空");
            return;
        }
        Emp temp=head;
        while(true){
            if (temp!=null){
                System.out.print(temp+"----->");
                temp=temp.next;
            }else {
                break;
            }
        }
        System.out.println("");
    }
    //改节点信息
    public void update(Emp newEmp){
        Emp temp=head;
        while(true){
            if(temp.no!=newEmp.no){
                temp=temp.next;
            }else {
                temp.name=newEmp.name;
                temp.nickname=newEmp.nickname;
                System.out.println("修改成功!");
                break;
            }
        }
    }
}

数组(用来管理链表的信息)

//创建数组来管理链表
class ArrList{
    public int size;
    //这里注意是建立数组来存储每个链表
    public SingleList[] lists;
    //初始化数组的个数的构造方法
    public ArrList(int size) {
        this.size = size;
        //对数组进行初始化
        lists=new SingleList[size];
        for(int i=0;i<size;i++){
            lists[i]=new SingleList();
        }
    }
    //哈希值,来判断插入的节点应该到哪一个链表上
    public int hashCode(int no){
        return no%size;
    }
    //增加员工
    public void add(Emp newEmp){
        int ListNo=hashCode(newEmp.no);
        lists[ListNo].add(newEmp);
    }
    //按照编号的大小添加员工
    public void addByOrder(Emp newEmp){
        int listNo=hashCode(newEmp.no);
        lists[listNo].addByOrder(newEmp);
    }
    //删除员工信息
    public void delete(int no){
        int listNo=hashCode(no);
        lists[listNo].delete(no);
    }
    //改员工的信息
    public void update(Emp node){
        int listNum=hashCode(node.no);
        //通过hash值来判断要加入链表的位置。
        lists[listNum].update(node);
    }
    //遍历所有节点
    public void displayAll(){
        for (int i=0;i<size;i++){
            lists[i].displayAll();
        }
    }
}

测试代码

public class HashTab2 {
    public static void main(String[] args) {
        ArrList hashTable=new ArrList(8);
        String key="";
        Scanner scanner=new Scanner(System.in);
        while (true){
            System.out.println("add:添加");
            System.out.println("list:显示");
            System.out.println("exit:退出");
            System.out.println("addByOrder:按照顺序添加");
            System.out.println("update:更改员工信息");
            System.out.println("delete:删除员工信息");
            System.out.println(" ");
            key=scanner.next();
            switch (key){
                case "add":
                    System.out.println("请输入雇员id:");
                    int id=scanner.nextInt();
                    System.out.println("请输入雇员姓名");
                    String name=scanner.next();
                    System.out.println("请输入雇员昵称");
                    String nickname=scanner.next();
                    Emp newEmp=new Emp(id,name,nickname);
                    hashTable.add(newEmp);
                    break;
                case "addByOrder":
                    System.out.println("请输入雇员id:");
                    id=scanner.nextInt();
                    System.out.println("请输入雇员姓名");
                    name=scanner.next();
                    System.out.println("请输入雇员昵称");
                    nickname=scanner.next();
                    newEmp=new Emp(id,name,nickname);
                    hashTable.addByOrder(newEmp);
                    break;
                case "delete":
                    System.out.println("请输入雇员id:");
                    id=scanner.nextInt();
                    hashTable.delete(id);
                    break;
                case "update":
                    System.out.println("请输入要修改的雇员id:");
                    id=scanner.nextInt();
                    System.out.println("请输入想要修改的雇员姓名");
                    name=scanner.next();
                    System.out.println("请输入想要修改的雇员昵称");
                    nickname=scanner.next();
                    newEmp=new Emp(id,name,nickname);
                    hashTable.update(newEmp);
                    break;
                case "list":
                    hashTable.displayAll();
                    break;

                case "exit":
                    scanner.close();
                    System.exit(0);
                default:
                    break;
            }
        }
    }
}

测试结果:


可以看出,可以实现很好的哈希表的数据结构。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值