Hash algorithm design principle and code implementation

One: The design principle of Hash algorithm

1: The principle of constructing a hash function is:

  • The function itself is easy to calculate
  • The calculated addresses are evenly distributed, that is, for any keyword K, H(K) has the same probability of corresponding to different addresses, and the purpose is to reduce conflicts as much as possible.

2: Common methods for constructing Hash functions

  • Divide and leave remainder method

If the length of the hash table is m and p is the largest prime number less than or equal to m, then the hash function is H(K)=K%p, where% is the remainder operation modulo P

  • Pseudo-random number method

Use a pseudo-random function as the hash function, namely H(key)=random(key)

Two: the method of dealing with Hash conflict

  • Rehashing

This method is to construct multiple different hash functions at the same time:

                   Hi = RHi(key), i =1,2,...,k

When the hash address H1 = RH1 (key) conflicts, then calculate H2 = RH2 (key)... until the conflict no longer occurs, this method is not easy to produce aggregation, but it increases the calculation time.

  • Chain address

All elements with a hash address of i are formed into a singly linked list called a synonym chain, and the head pointer of the singly linked list is stored in the I-th unit of the hash table. Therefore, search, insertion and deletion are mainly performed in the synonym linked list. The chain address method is suitable for frequent insertions and deletions.

  • Establish a public overflow area

The basic idea of ​​this method is to divide the hash table into two parts: the basic table and the overflow table. All elements that conflict with the basic table are filled into the overflow table.

Two: the realization of Hash code

Employee entity class:

package com.test;

/**
 * @author lizhangyu
 * @date 2021/3/6 12:23
 */
public class Employee {

    public int id;
    public String name;
    public Employee next;

    public Employee(int id, String name) {
        this.id = id;
        this.name = name;
    }
}
EmpLinkedList entity class
package com.test;

/**
 * @author lizhangyu
 * @date 2021/3/6 12:26
 */
public class EmpLinkedList {

    private Employee head;

    /**
     * 添加
     * @param employee
     */
    public void add(Employee employee) {
        if (head == null) {
            head = employee;
            return;
        }

        Employee cur = head;

        while (true) {
            if (cur.next == null) {
                break;
            }
            cur = cur.next;
        }

        cur.next = employee;
    }

    /**
     * 遍历链表
     * @param no
     */
    public void list(int no) {
        if (head == null) {
            System.out.println("第" + (no + 1) + "条链表为空" );
            return;
        }
        System.out.print("第" + (no + 1) + "条链表信息为");
        Employee 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();
    }

    /**
     * 查找
     * @param id
     * @return
     */
    public Employee find(int id) {
        if (head == null) {
            System.out.println("链表为空");
            return null;
        }

        Employee cur = head;

        while (true) {
            if (cur.id == id) {
                break;
            }

            if (cur.next == null) {
                cur = null;
                break;
            }

            cur = cur.next;
        }

        return cur;
    }

}
HashTable entity class:
package com.test;

/**
 * @author lizhangyu
 * @date 2021/3/6 12:06
 */
public class HashTable {

    private int size;
    private EmpLinkedList[] empLinkedListArray;

    public HashTable(int size) {
        this.size = size;
        this.empLinkedListArray = new EmpLinkedList[size];
        //初始化链表
        for (int i = 0; i < size ; i++) {
            empLinkedListArray[i] = new EmpLinkedList();
        }
    }

    /**
     * 查找
     * @param id
     */
    public void find(int id) {
        int empLinkedListNO = hashFun(id);
        Employee employee = empLinkedListArray[empLinkedListNO].find(id);
        if (employee != null) {
            System.out.printf("在第%d条链表中找到雇员id = %d\n", (empLinkedListNO + 1), id);
        }else {
            System.out.println("在哈希表中中找到雇员");
        }
    }

    /**
     * 遍历
     */
    public void list() {
        for (int i = 0; i < size; i++) {
            empLinkedListArray[i].list(i);
        }
    }

    /**
     * 添加
     * @param employee
     */
    public void add(Employee employee) {
        int employeeNo = hashFun(employee.id);
        empLinkedListArray[employeeNo].add(employee);
    }

    /**
     * 取模运算
     * @param id
     * @return
     */
    public int hashFun(int id) {
        return id % size;
    }
}
HashTableDemo test class
package com.test;

import java.util.Scanner;

/**
 * @author lizhangyu
 * @date 2021/3/6 12:45
 */
public class HashTableDemo {

    public static void main(String[] args) {
        HashTable hashTable = new HashTable(7);
        String key = "";
        Scanner scanner = new Scanner(System.in);

        while (true) {
            System.out.println("add: 添加雇员");
            System.out.println("list: 显示雇员");
            System.out.println("find: 查找雇员");
            System.out.println("exit: 退出系统");
            key = scanner.next();
            switch (key) {
                case "add" :
                    System.out.println("请输入员工id");
                    int id = scanner.nextInt();
                    System.out.println("请输入员工名字");
                    String name = scanner.next();
                    Employee employee = new Employee(id, name);
                    hashTable.add(employee);
                    break;
                case "find" :
                    System.out.println("请输入员工id");
                    id = scanner.nextInt();
                    hashTable.find(id);
                    break;
                case "list" :
                    hashTable.list();
                    break;
                case "exit" :
                    scanner.close();
                    System.exit(0);
                default:
                    break;
            }
        }
    }
}

 

Guess you like

Origin blog.csdn.net/qq_37469055/article/details/114435800