内功之--哈希表

一.什么是哈希表

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

    内功之--哈希表_第1张图片

二.实现一个需求

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

 

  • 不使用数据库,速度越快越好。
  • 添加时,保证按照 id 从低到高插入。-----》使用id/size作为hash值。
  • 使用链表来实现哈希表, 该链表不带表头。

 

  • 原理图:

内功之--哈希表_第2张图片

代码:

public class HashDemo {
	public static void main(String[] args) {
		//创建哈希表
		HashTable hashTab = 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();
				//创建 雇员
				Emplyee emp = new Emplyee(id, name);
				hashTab.addEmp(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;
			}
		}
	}
}

//hashtable

class HashTable {
	private EmpLinkedList[] empLinkedLists;// 存放链表的集合
	private int size;// 数组大小

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

	// 添加emp
	public void addEmp(Emplyee emp) {
		int hash = calculateHashValue(emp.getId());
		empLinkedLists[hash].addEmp(emp);
	}
	
	//遍历list
	
	public void list() {
		for (int i = 0; i < empLinkedLists.length; i++) {
			empLinkedLists[i].list(i);
		}
	}
	
	//找到id对应的结点
	public void findEmpById(int no) {
		int hash = calculateHashValue(no);
		empLinkedLists[hash].findEmpById(no);
	}

	// 哈希值h
	public int calculateHashValue(int id) {
		return id % size;
	}
}

//构造链表
class EmpLinkedList {
	// 头结点
	Emplyee head = null;

	// 添加结点
	public void addEmp(Emplyee emp) {
		// 头节点为空,直接添加
		if (head == null) {
			head = emp;
			return;
		}
		Emplyee temp = head;
		while (true) {
			if (temp.next == null) {// 说明到了链表尾部
				break;
			}
			temp = temp.next;
		}
		temp.next = emp;
	}

	// 遍历链表

	public void list(int no) {
		if (head == null) {// 空链表
			System.out.println("第"+(no+1)+"空链表");
			return;
		}

		Emplyee temp = head;
		System.out.print("第"+(no+1)+"链表的信息为");
		while (true) {
			System.out.printf("==>id=%d,name=%s\t", temp.getId(), temp.getName());
			System.out.println();
			if (temp.next == null) {// 链表尾结束
				break;
			}
			temp = temp.next;
		}
	}

	// 根据id遍历
	public void findEmpById(int no) {
		if (head == null) {
			return;
		}

		Emplyee temp = head;
		while (true) {
			if (temp.getId() == no) {
				System.out.printf("==>id=%d,name=%s\t", temp.getId(), temp.getName());
				break;
			}
			if (temp.next == null) {
				break;
			}
			temp = temp.next;
		}
	}
}

//链表结点---雇员
class Emplyee {
	private int id;
	private String name;
	Emplyee next;

	public int getId() {
		return id;
	}

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

	public String getName() {
		return name;
	}

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

	public Emplyee getNext() {
		return next;
	}

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

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

}

 总结:每条链表在构造时要进行初始化。

 

 

你可能感兴趣的:(java)