散列(哈希)表实现
定义
1)散列表也叫做哈希表,是根据关键码值(key,value)来进行访问的数据结构,例如java中的hashmap/hashtable。
2)哈希表可以使用数组+链表实现或者数组+二叉树实现
分析
用数组+链表实现哈希表
1)数组存储首个链表节点位置
2)链表内每个节点位置记录下一个链表节点位置
代码实现
需求:设计一个散列表用于存储班级以及学生(可以有多个班级,每个班级有多个学生)
/**
* 具体存储的数据(学生)
* */
public class Student {
private int id;
private String name;
private int age;
//指向下一个链表节点.
private Student nextStudent;
public Student(int id, String name, int age) {
this.id = id;
this.name = name;
this.age = age;
}
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 int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Student getNextStudent() {
return nextStudent;
}
public void setNextStudent(Student nextStudent) {
this.nextStudent = nextStudent;
}
}
/**
* 单链表实现(相当于一个班级,存储多个学生)
* */
public class StudentList {
//数组中链表头指向第一个学生
private Student head;
/**
* 班级添加学生
* */
public void addStudent(Student student){
//如果是空列表则直接添加到第一个位置即可
if(head==null){
head = student;
}else{
Student helperHead = head;
while(true){
//获取到最后一个元素位置
if(helperHead.getNextStudent()==null){
break;
}
helperHead = helperHead.getNextStudent();
}
helperHead.setNextStudent(student);
}
}
/**
* 遍历班级学生
* */
public void eroglic(){
Student helperStudent = head;
while(true){
System.out.println("名字:"+helperStudent.getName()+"年龄:"+helperStudent.getAge());
if(helperStudent.getNextStudent()==null){
break;
}
helperStudent= helperStudent.getNextStudent();
}
}
/**
* 根据学生id删除某个学生
* */
public void delStudent(int studentId){
Student helperStudent = head;
Student pre = null;
if(helperStudent.getId()==studentId) {
//如果首节点是对应删除id 则把首节点指向下一个节点
Student nextStudent = helperStudent.getNextStudent();
head = nextStudent;
}else
{
while(true){
if(helperStudent==null){
break;
}
pre = helperStudent;
if(helperStudent.getNextStudent().getId()==studentId){
pre.setNextStudent(helperStudent.getNextStudent().getNextStudent());
}
helperStudent = helperStudent.getNextStudent();
}
}
}
}
/**
* 定义散列表 里面包含班级数组(存储多个班级)
* */
public class HashTab {
//定义存储班级的数组
StudentList [] studentListArray = null;
//定义最多存储多少个班级
private int maxSize;
//构造函数初始化参数
public HashTab(int max){
this.maxSize = max;
if(studentListArray==null){
studentListArray = new StudentList[maxSize];
for(int i = 0;i<max;i++){
//每一个都需要实例化否则会空指针
studentListArray[i] = new StudentList();
}
}
}
//获取对应班级存储位置(求模获取)
public int getPosition(int classId){
return classId%maxSize;
}
//班级添加一个学生
public void addStudentByClass(int classId,Student student){
int position = getPosition(classId);
StudentList studentList = studentListArray[position];
studentList.addStudent(student);
}
//遍历某个班级学生
public void eroglic(int classId){
int position = getPosition(classId);
StudentList studentList = studentListArray[position];
studentList.eroglic();
}
/**
* 根据班级id以及学生id删除某个学生
* */
public void delByClassIdAndStudentId(int classId,int studentId){
int position = getPosition(classId);
StudentList studentList = studentListArray[position];
studentList.delStudent(studentId);
}
}
测试
public static void main(String[] args) {
HashTab hashTab = new HashTab(10);
hashTab.addStudentByClass(1,new Student(1,"张三",10));
hashTab.addStudentByClass(1,new Student(2,"里斯",10));
hashTab.addStudentByClass(2,new Student(2,"王五",10));
System.out.println("一班遍历-------------------------------------");
hashTab.eroglic(1);
hashTab.delByClassIdAndStudentId(1,2);
System.out.println("删除1班2号同学后遍历---------------------------------");
hashTab.eroglic(1);
System.out.println("二班遍历---------------------------------");
hashTab.eroglic(2);
}