哈希表

哈希表的基本介绍:

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

java 哈希表 哪些对象 java中哈希表的使用_数据结构


google公司的一个上机题:

有一个公司,当有新的员工来报道时,要求将该员工的信息加入(id,性别,年龄,住址…),当输入该员工的id时,要求查找到该员工的 所有信息.
要求: 不使用数据库,尽量节省内存,速度越快越好=>哈希表(散列)

为了简化,员工信息只有名字,存储时按id从大到小存,能够添加、查询、删除每个雇员、显示所有链表的情况:

import java.util.Scanner;

public class HashTabDemo {

	public static void main(String[] args) {

		// 创建哈希表
		HashTab hashTab = new HashTab(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("delete: 删除雇员");
			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();
				// 创建 雇员
				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 "delete":
				System.out.println("请输入要删除的id");
				id=scanner.nextInt();
				hashTab.deleteEmpById(id);
				break;
			case "exit":
				scanner.close();
				System.exit(0);
			default:
				break;
			}
		}
	}

}

// 创建HashTab 管理多链表
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);
	}

	// 遍历所有的链表
	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.println("在第"+(empLinkedListNo+1)+"条链表中找到id为"+id+"的雇员");
		}else {
			System.out.println("没有找到该雇员");
		}
	}
	
	//根据id删除雇员
	public void deleteEmpById(int id) {
		int empLinkedListNo = hashFun(id);
		empLinkedListArray[empLinkedListNo].deleteEmpById(id);
	}

	// 编写散列函数,使用最简单的取模法进行编写
	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;
	}

	@Override
	public String toString() {
		return "Emp [id=" + id + ", name=" + name + "]";
	}

}

// 创建一个链表
class EmpLinkedList {
	// 头指针,这里的head就是链表中第一个节点
	public Emp head;

	// 添加雇员,按id从小到大添加
	public void add(Emp emp) {
		if (head == null) {// 若果添加第一个雇员
			head = emp;
			return;
		}
		if(head.id>emp.id) {//当第一个节点的id比待插入节点的id大时
			emp.next=head;
			head=emp;
			return;
		}
		// 辅助指针
		Emp temp = head;
		while (temp.next != null) {// 直到链表的最后
			if(temp.next.id>emp.id) {//当找到插入位置时
				emp.next=temp.next;
				temp.next=emp;
				return;
			}
			temp=temp.next;
		}
		temp.next = emp;// 当待插入节点的id比链表最后一个的id还大时
	}

	// 遍历链表
	public void list(int no) {
		if (head == null) {// 链表为空
			System.out.println("第"+(no+1)+"条链表为空");
			return;
		}
		Emp temp = head;// 辅助指针
		System.out.print("第"+(no+1)+"条链表信息为:");
		while (temp != null) {
			System.out.print(temp + "   ");
			temp = temp.next;
		}
		System.out.println();
	}
	
	//根据id查找雇员
	//找到则返回Emp,没有找到返回null
	public Emp findEmpById(int id) {
		//判断链表是否为空
		if(head==null) {
			return null;
		}
		//辅助指针
		Emp temp=head;
		while(temp!=null) {
			if(temp.id==id) {//查找到则退出
				break;
			}
			temp=temp.next;//后移
		}
		return temp;
	}
	
	//删除节点
	public void deleteEmpById(int id) {
		if(head==null) {
			System.out.println("没有该雇员,删除失败");
			return;
		}
		if(head.id==id) {//当删除的是第一个节点时
			head=head.next;
			System.out.println("删除成功");
			return;
		}
		Emp temp=head;
		while(temp.next!=null) {
			if(temp.next.id==id) {
				temp.next=temp.next.next;
				System.out.println("删除成功");
				return;
			}
			temp=temp.next;
		}
		System.out.println("没有该雇员,删除失败");
	}
}