哈希表的增、删、查、遍历

package com.zzb.hashtable;

import java.io.Serializable;

/**
 * @Auther: Administrator
 * @Date: 2019/10/7 00:44
 * @Description: 哈希表的增、删、查、遍历
 *
 * 哈希表数据结构 就是 数组数据结构 与 链表数据结构 的组合而构成的,即
 * 哈希表 = 数组 + 链表
 *
 * 有一个公司,当有新的员工来报道时,要求将该员工的信息加入(id,性别,年龄,名字,住址...),当输入该员工的id时,
 * 要求查找到该员工的所有信息
 *
 * 要求:
 * (1)不使用数据库,,速度越快越好=>哈希表(散列表)
 * (2)添加时,保证按照id从低到高插入(如果id不是从低到高插入,但要求各条链表中的id仍是从低到高,
 *  则需要进行判断后再添加,参考 https://blog.csdn.net/qq_16645099/article/details/101919137
 *  单链表有序添加节点的代码 addByOrder)
 * (3)使用链表来实现哈希表, 该链表不带表头(即链表的第一个结点就存放雇员信息)
 */
public class HashTableDemo01 {
    public static void main(String[] args) {
        HashTable hashTable = new HashTable(7);
        // 向哈希表中添加元素
        hashTable.add(new Employee(1, "aa"));
        hashTable.add(new Employee(2, "bb"));
        hashTable.add(new Employee(3, "cc"));
        hashTable.add(new Employee(4, "dd"));
        hashTable.add(new Employee(5, "ee"));
        hashTable.add(new Employee(6, "ff"));
        hashTable.add(new Employee(7, "gg"));
        hashTable.add(new Employee(8, "hh"));
        hashTable.add(new Employee(9, "ii"));
        hashTable.add(new Employee(10, "jj"));
        // 遍历哈希表
        hashTable.list();
        // 在哈希表中查找元素
        System.out.println("在哈希表中查找元素 " + hashTable.findOneById(10));

        /*----------------第 1 条链表中的元素信息如下----------------
        Employee{id=7, name='gg'}
        ----------------第 2 条链表中的元素信息如下----------------
        Employee{id=1, name='aa'}
        Employee{id=8, name='hh'}
        ----------------第 3 条链表中的元素信息如下----------------
        Employee{id=2, name='bb'}
        Employee{id=9, name='ii'}
        ----------------第 4 条链表中的元素信息如下----------------
        Employee{id=3, name='cc'}
        Employee{id=10, name='jj'}
        ----------------第 5 条链表中的元素信息如下----------------
        Employee{id=4, name='dd'}
        ----------------第 6 条链表中的元素信息如下----------------
        Employee{id=5, name='ee'}
        ----------------第 7 条链表中的元素信息如下----------------
        Employee{id=6, name='ff'}
        在哈希表中查找元素 Employee{id=10, name='jj'}*/
    }
}

// 创建模拟哈希表
class HashTable {
    private LinkedList[] array;
    // 哈希表中链表的个数
    private Integer size;

    public HashTable() {
        this(10);
    }

    // 创建哈希表时,数组的长度指定,也即单链表集合的个数
    public HashTable(Integer size) {
        this.size = size;
        array = new LinkedList[size];
        // 初始化数组中的各个链表元素
        for (int i = 0; i < size; i++) {
            array[i] = new LinkedList();
        }
    }

    // 向哈希表添加元素
    public void add(Employee employee) {
        // 求出数组中的目标链表
        Integer index = hashIndex(employee.getId());
        this.getArray()[index].add(employee);
    }

    // 在哈希表中查找特定元素
    public Employee findOneById(Integer id) {
        // 求出数组中的目标链表
        Integer index = hashIndex(id);
        return this.getArray()[index].findOneById(id);
    }

    // 遍历哈希表
    public void list() {
        for (int i = 0; i < this.getSize(); i++) {
            this.getArray()[i].list(i);
        }
    }

    // 散列函数,求取元素所在的位置,简单取模法
    public Integer hashIndex(Integer id) {
        return id % this.getSize();
    }


    public LinkedList[] getArray() {
        return array;
    }

    public void setArray(LinkedList[] array) {
        this.array = array;
    }

    public Integer getSize() {
        return size;
    }

    public void setSize(Integer size) {
        this.size = size;
    }
}

// 创建模拟单链表集合
class LinkedList {
    // 头指针,执行第一个employee,因此我们这个链表的head是直接指向第一个employee
    private Employee head; // 默认为null

    public Employee getHead() {
        return head;
    }

    public void setHead(Employee head) {
        this.head = head;
    }

    /**
     * 添加元素
     * 假定,当添加雇员时,id是自增长,即id的分配总是从小到大
     * 因此直接将元素加入到本链表的最后即可
     * @param employee
     */
    public void add(Employee employee) {
        if(this.getHead() == null) { // 当前链表没有元素
            head = employee;
            return;
        } else { // 当前链表已有元素
            Employee temp = this.getHead();
            while(true) {
                if(temp.getNext() == null) { // temp为next属性为null的末尾元素
                    break;
                }
                // 后移
                temp = temp.getNext();
            }
            // 退出循环,添加元素到末尾
            temp.setNext(employee);
        }
    }

    // 查找元素
    public Employee findOneById(Integer id) {
        if(this.getHead() == null) {
            System.out.println("链表为空!");
            return null;
        } else {
            Employee temp = this.getHead();
            while(true) {
                if(temp.getId() == id) {
                    break;
                } else {
                    if(temp.getNext() == null) { // 遍历到末尾元素都没有找到指定元素
                        temp = null;
                        break;
                    }
                    // 后移
                    temp = temp.getNext();
                }
            }
            return temp;
        }
    }

    // 遍历元素
    public void list(Integer index) {
        if(this.getHead() == null) {
            System.out.println("第 " + (index+1) + " 条链表为空!");
            return;
        } else {
            System.out.println("----------------第 " + (index+1) + " 条链表中的元素信息如下----------------");
            Employee temp = this.getHead();
            while(true) {
                System.out.println(temp);
                if(temp.getNext() == null) { // 遍历到最后一个元素了
                    break;
                } else {
                    temp = temp.getNext();
                }
            }
        }
    }
}

// 员工节点类
class Employee implements Serializable {

    private static final long serialVersionUID = 3094191959099739635L;

    private Integer id;
    private String name;
    private Employee next; // 指向下一个元素的引用,默认为空

    public Employee() {

    }

    public Employee(Integer id, String name) {
        this.id = id;
        this.name = name;
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Employee getNext() {
        return next;
    }

    public void setNext(Employee next) {
        this.next = next;
    }

    @Override
    public String toString() {
        return "Employee{" +
                "id=" + id +
                ", name='" + name + '\'' +
                '}';
    }
}

 

你可能感兴趣的:(数据结构)