1.问题:
需求:有一个公司,当有新员工来报道时,要求将该员工的信息加入(id,性别,年龄,名字,住址,,),
- 当输入该员工的id时,要求查到该员工的所有信息。
- 要求:不使用数据库
2.简略图解
3.思路:
a.创建一个雇员,此时暂时只考虑id和name
//表示一个雇员
class Emp{
public int id;
public String name;
public Emp next;//默认为null
public Emp(int id, String name) {
super();
this.id = id;
this.name = name;
}
}
b.创建一条EmpLinkedList链表,链表正常操作,增(新增员工)删(删除原)查(根据id查找员工信息)
//创建EmpLinkedList,表示链表
class EmpLinkedList {
//创建头指针head,head指向第一个Emp,就不用一个虚拟头节点 了
private Emp head;//默认为null
//添加雇员到链表
/*
* 说明:1.假定当添加雇员时,id是自增长,即id的分 配是从小到大,因此直接将该雇员加到本链表的最后即可
*
*/
public void add(Emp emp) {
//如果添加第一个雇员
if(head == null) {
head = emp;
return;
}
//如果不是添加第一个雇员,则使用一个辅助指针
Emp cur = head;
while(true) {
if(cur.next == null) {
//说明到链表的最后了
break;
}
cur = cur.next;
}
//退出循环时说明已经遍历到链表最后了
cur.next = emp;
}
//遍历雇员信息
public void list(int no) {
if(head == null) {
//说明链表为空
System.out.println("第"+(no+1)+"链表为空");
return;
}
System.out.print("第"+(no+1)+"链表的信息为:");
Emp cur = head;
while(true) {
System.out.print("=> id=" + cur.id +" "+ "name=" + cur.name+" ");
if(cur.next == null) {
break;
}
cur = cur.next;
}
System.out.println();
}
//根据id 查找雇员
//如果找到就返回,找不到返回空
public Emp findEmpById(int id) {
if(head == null) {
System.out.println("链表为空");
return null;
}
Emp cur = head;
while(true) {
if(cur.id == id) {
//找到
break;
}
//退出
if(cur.next == null) {
cur = null;//此时没找到,置空就行
}
cur = cur.next;
}
return cur;
}
}
c.创建哈希表,用来管理多条链表,注意在HashTab中也需要编写增删查等方法,然后调用EmpLinkedList里面的具体方法,相当于我们能看见的只有HashTab,但是具体实现的方法却在EmpLinkedList中
class HashTab {
private EmpLinkedList[] empLinkedListArr;
private int size;//表示共有多少条链表
//构造器
public HashTab(int size) {
this.size = size;
//初始化empLinkedListArr
empLinkedListArr = new EmpLinkedList[size];
//此时不能忘了初始化每一个链表,否则会报空指针异常,因为链表此时为null
for(int i = 0; i < size; i++) {
empLinkedListArr[i] = new EmpLinkedList();
}
}
//添加雇员
public void add(Emp emp) {
//根据雇员的id,得到该员工应当添加到那条链表
int empLinkedListNo = hashNo(emp.id);
//将emp添加到对应的链表
empLinkedListArr[empLinkedListNo].add(emp);
}
//遍历HashTable
public void list() {
for(int i = 0; i < size; ++i) {
empLinkedListArr[i].list(i);
}
}
//编写散列函数,
public int hashNo(int id) {
return id % size;
}
//根据id 查找雇员
public void findEmpById(int id) {
//使用散列函数确定到哪条链表去找
int empLinkedListNo = hashNo(id);
Emp emp = empLinkedListArr[empLinkedListNo].findEmpById(id);
if(emp != null) {
//找到
System.out.println("在第"+(empLinkedListNo+1)+"条链表中找到雇员,id="+id);
} else {
System.out.println("在哈希表中,没有找到该雇员");
}
}
}
d.写一个简单的菜单来测试:
public static void main(String[] args) {
//创建哈希表
HashTab hashTab = new HashTab(7);
//写一个简单的菜单
String key = "";
Scanner sc = new Scanner(System.in);
while(true) {
System.out.println("add: 添加雇员");
System.out.println("list: 显示雇员");
System.out.println("exit: 退出系统");
System.out.println("find: 查找雇员");
key = sc.next();
switch(key) {
case "add":
System.out.println("输入id");
int id = sc.nextInt();
System.out.println("输入姓名");
String name = sc.next();
//创建雇员
Emp emp = new Emp(id,name);
hashTab.add(emp);
break;
case "list":
hashTab.list();
break;
case "find":
System.out.println("请输入要查找的id");
id = sc.nextInt();
hashTab.findEmpById(id);
break;
case "exit":
sc.close();
System.exit(0);
}
}
}
4.学习心得:具体方法虽然都是链表的操作,但还是有些之前学了就忘了。需要不断练习和学习。菜单写的也很好玩。