JAVA代码实现哈希表

哈希表

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

  • 举例:定义一个哈希表实现员工的增删改查
package com.hashTab;

import java.util.Scanner;

/*
 * 使用哈希表完成员工的增删改查
 */
public class HashTabDemo2 {

	public static void main(String[] args) {
		// 创建哈希表
		HashTab1 hashTab = new HashTab1(5);
		// 写一个简单的菜单
		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("update:修改雇员信息");
			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();
				Employe emp = new Employe(id, name);
				hashTab.add(emp);
				break;
			case "list":
				hashTab.list();
				break;
			case "find":
				System.out.println("请输入要查找的id");
				int findId = scanner.nextInt();
				hashTab.findById(findId);
				break;
			case "delete":
				System.out.println("请输入雇员编号");
				int deleteId = scanner.nextInt();
				hashTab.deleteByID(deleteId);
				break;
			case "update":
				System.out.println("请输入雇员编号");
				int updateId = scanner.nextInt();
				System.out.println("请输入雇员姓名");
				String updateName = scanner.next();
				hashTab.updateById(new Employe(updateId, updateName));
				break;
			case "exit":
				scanner.close();
				System.exit(0);
				break;

			default:
				break;
			}
		}

	}

}

//定义哈希表
class HashTab1 {
	private EmployeLinkedList[] empLinkedListArray;
	private int size;// 哈希表中链表的个数

	public HashTab1(int size) {
		this.size = size;
		// 初始化链表数组
		empLinkedListArray = new EmployeLinkedList[size];
		// 数组中的每个链表也要创建,否则会报空指针
		for (int i = 0; i < empLinkedListArray.length; i++) {
			empLinkedListArray[i] = new EmployeLinkedList();
		}
	}

	// 按取模的方式创建散列函数
	public int hashFun(int id) {
		return id % size;
	}

	// 添加员工
	public void add(Employe emp) {
		int i = hashFun(emp.getId());
		empLinkedListArray[i].addById(emp);
	}

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

	// 根据id查找员工
	public void findById(int id) {
		int i = hashFun(id);
		Employe employe = empLinkedListArray[i].findById(id);
		if (employe == null) {
			System.out.printf("没有找到编号为%d的员工\n", id);
		} else {
			System.out.printf("编号为%d的员工姓名是:%s\n", id, employe.getName());
		}
	}

	// 根据id删除员工
	public void deleteByID(int id) {
		int i = hashFun(id);
		empLinkedListArray[i].deleteById(id, i);
	}

	// 根据id修改员工信息
	public void updateById(Employe emp) {
		int i = hashFun(emp.getId());
		empLinkedListArray[i].updateById(emp, i);
	}
}

//定义链表
class EmployeLinkedList {
	private Employe head;// 头节点

	// 按id顺序添加员工
	public void addById(Employe emp) {
		if (head == null) {// 第一次添加员工
			head = emp;
			return;
		}
		// 如果不是第一次添加,就先找到添加位置
		Employe temp = head;
		if (head.getId() > emp.getId()) {
			head = emp;
			head.setNext(temp);
			return;
		}
		boolean flag = false;
		while (true) {
			if (temp.getNext() == null) {// 如果遍历到最后,还没找到,就在最后添加就行
				break;
			}
			if (temp.getNext().getId() > emp.getId()) {// 如果temp的下一个节点的id大于要插入的id,那就在temp后面添加
				flag = true;
				break;
			}
			temp = temp.getNext();
		}
		if (flag) {
			emp.setNext(temp.getNext());
			temp.setNext(emp);
		} else {
			temp.setNext(emp);
		}
	}

	// 遍历链表
	public void list(int i) {
		if (head == null) {
			System.out.printf("第%d链表为空\n", i + 1);
			return;
		}
		System.out.printf("第%d链表信息为:", i + 1);
		Employe temp = head;
		while (true) {
			System.out.printf("=> id=%d,name=%s\t", temp.getId(), temp.getName());
			if (temp.getNext() == null) {
				break;
			}
			temp = temp.getNext();
		}
		System.out.println();
	}

	// 根据id查找雇员
	public Employe findById(int id) {
		if (head == null) {
			return null;
		}
		Employe temp = head;
		while (true) {
			if (temp.getId() == id) {
				break;
			}
			if (temp.getNext() == null) {
				temp = null;
				break;
			}
			temp = temp.getNext();
		}
		return temp;
	}

	// 根据id删除员工
	public void deleteById(int id, int i) {
		if (head == null) {
			System.out.printf("第%d链表为空,没有编号为%d的员工\n", i + 1, id);
			return;
		}
		Employe temp = head;
		if (head.getId() == id) {
			head = head.getNext();
			System.out.printf("编号为%d的员工已删除\n", id);
			return;
		}
		boolean flag = false;
		while (true) {
			if (temp.getNext() == null) {
				break;
			}
			if (temp.getNext().getId() == id) {
				flag = true;
				break;
			}
			temp = temp.getNext();
		}
		if (flag) {
			temp.setNext(temp.getNext().getNext());
			System.out.printf("编号为%d的员工已删除\n", id);
		} else {
			System.out.printf("没有找到编号为%d的员工\n", id);
		}
	}

	// 根据id修改员工信息
	public void updateById(Employe emp, int i) {
		if (head == null) {
			System.out.printf("第%d链表为空,没有编号为%d的员工\n", i + 1, emp.getId());
			return;
		}
		Employe temp = head;
		if(head.getId()==emp.getId()) {
			head.setName(emp.getName());
			System.out.println("修改成功");
			return;
		}
		boolean flag = false;
		while (true) {
			if (temp.getNext() == null) {
				break;
			}
			if (temp.getId() == emp.getId()) {
				flag = true;
				break;
			}
			temp = temp.getNext();
		}
		if (flag) {
			temp.setName(emp.getName());
			System.out.println("修改成功");
		} else {
			System.out.printf("没有编号为%d的员工\n", emp.getId());
		}
	}

}

//定义员工类
class Employe {
	private int id;// 员工编号
	private String name;// 员工姓名
	private Employe 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 Employe getNext() {
		return next;
	}

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

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

}

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值