zoukankan      html  css  js  c++  java
  • 哈希表(散列)

    哈希表的基本介绍

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

    哈希表使用案例

    ●有一个公司,当有新的员工来报道时,要求将该员工的信息加入(id,性别,年龄,名字,住址.),当输入该员工的id时要求查找到该员工所有信息息

    要求:

    不使用数据库,速度越快越好=>哈希表(散列)。添加时,保证按照id从低到高插入

    ➢使用链表来实现哈希表,该链表不带表头[即:链表的第一个结点就存放雇员信息]
    ➢思路分析并画出示意图

    ➢代码实现[增改查(显示所有员工, 按id查询)]

    package com.xudong.DataStructures;
    
    import java.util.Scanner;
    
    public class HashTableDemo {
        public static void main(String[] args) {
            //创建hashTab
            HashTab hashTab = new HashTab(7);
            //写一个简单的菜单
            String key = "";
            Scanner scanner = new Scanner(System.in);
            while (true){
                System.out.println("--------------");
                System.out.println("add:  添加雇员");
                System.out.println("list: 显示雇员");
                System.out.println("find: 查找雇员");
                System.out.println("exit: 退出程序");
                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();
                        //创建雇员
                        Emp emp = new Emp(id,name);
                        hashTab.add(emp);
                        break;
                    case "list":
                        hashTab.list();
                        break;
                    case "find":
                        System.out.println("输入要查找的 id:");
                        id = scanner.nextInt();
                        hashTab.findEmpById(id);
                        break;
                    case "exit":
                        scanner.close();
                        System.exit(0);
                    default:
                        break;
                }
            }
        }
    }
    
    //创建哈希表,管理多条链表
    class HashTab{
        private EmpLinkedList[] empLinkedListArray;
        private int size;
    
        public HashTab(int size){
            this.size = size;
            //初始化empLinkedListArray
            empLinkedListArray = new EmpLinkedList[size];
            //分别初始化每个链表
            for (int i = 0; i < size; i++) {
                empLinkedListArray[i] = new EmpLinkedList();
            }
        }
    
        //添加雇员
        public void add(Emp emp){
            //根据员工id得到该员工应当添加到哪条链表
            int empLinkedListNO = hashFun(emp.id);
            //将emp添加到对应链表中
            empLinkedListArray[empLinkedListNO].add(emp);
        }
    
        //遍历所有链表,遍历hashTab
        public void list(){
            for (int i = 0; i < size; i++) {
                empLinkedListArray[i].list(i);
            }
        }
    
        //根据输入的id查找雇员
        public void findEmpById(int id){
            //使用散列函数确定到哪条链表查找
            int empLinkedListNO = hashFun(id);
            Emp emp = empLinkedListArray[empLinkedListNO].findEmpById(id);
            if (emp != null){
                System.out.printf("在第%d条链表找到雇员 id= %d
    ",(empLinkedListNO + 1),id);
            }else {
                System.out.println("在哈希表中没有找到该雇员!");
            }
        }
    
    
        //使用简单取模法编写散列函数
        public int hashFun(int id){
            return id % size;
        }
    }
    
    //表示一个雇员
    class Emp{
        public int id;
        public String name;
        public Emp next;//指向下一个员工的索引
    
        public Emp(int id, String name) {
            super();
            this.id = id;
            this.name = name;
        }
    }
    
    //创建链表
    class EmpLinkedList{
        private Emp head;//头指针,默认为null
        //添加雇员到链表,假定添加员工的id是自增的
        public void add(Emp emp){
            //如果是添加第一个雇员
            if (head == null){
                head = emp;
                return;
            }
            //如果不是第一个雇员,则用一个辅助指针,帮助定位到最后一个雇员的后面
            Emp curEmp = head;
            while (true){
                if (curEmp.next == null){//说明到链表最后
                    break;
                }
                curEmp = curEmp.next;//索引后移
            }
            //退出循环时将emp加入链表
            curEmp.next = emp;
        }
    
        //遍历链表的员工的信息
        public void list(int no){
            if (head == null){
                System.out.println("第"+ (no + 1) +"条链表为空!");
                return;
            }
            System.out.print("第"+ (no + 1) +"条链信息为:");
            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查找雇员
        public Emp findEmpById(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;
                    break;
                }
                curEmp = curEmp.next;//后移
            }
            return curEmp;
        }
    }
    
  • 相关阅读:
    移动端网页使用flexible.js加入百度联盟广告样式不一致问题解决
    flexible.js移动端适配安卓高分辨不兼容问题
    vue select二级城市联动及第二级默认选中第一个option值
    设置滚动条样式
    windows mongodb最常用命令简单归纳
    vue用阿里云oss上传图片使用分片上传只能上传100kb以内的解决办法
    vue实现文章内容过长点击阅读全文功能
    vue获取dom元素注意问题
    input框取消光标颜色手机端不生效
    基于 Vue.js 的移动端组件库mint-ui实现无限滚动加载更多
  • 原文地址:https://www.cnblogs.com/nnadd/p/13432503.html
Copyright © 2011-2022 走看看