概述
哈希表,也叫散列表,是**根据关键码值而直接进行访问的数据结构。**也就是说,它通过把关键码值映射到表中的一个位置来访问记录,以此来加快查找的速度,这个映射函数叫做散列函数,存放记录的数组叫做散列表
应用场景
代码实现(数组+链表)
- 哈希表的实现可以使用数组+链表或者使用数组+二叉树两种方式,下面采取第一种
/***
* 哈希表
* @author laowa
*
*/
class ArrayLinkedListHashTable {
/**
* 存放链表的数组
*/
private SingleLinkedList[] linkedListArray;
/**
* 哈希表构造器
*
* @param size
* 哈希表容量大小
*/
public ArrayLinkedListHashTable(int size) {
//初始化数组,但是这一步数组中所有元素都是初始值null
linkedListArray = new SingleLinkedList[size];
//为数组中每一个链表初始化
for(int i=0;i<size;i++) {
linkedListArray[i]=new SingleLinkedList();
}
}
/**
* 添加结点
* @param node
*/
public void add(Node node) {
linkedListArray[hashFunction(node.id)].add(node);
}
/**
* 删除结点
* @param id 待删除的结点id
*/
public void delete(int id) {
linkedListArray[hashFunction(id)].delete(id);
}
/**
* 通过id获取结点
* @param id 结点id
* @return 结点
*/
public Node getById(int id) {
return linkedListArray[hashFunction(id)].get(id);
}
/**
* 打印哈希表
*/
public void list() {
for(int i=0;i<linkedListArray.length;i++) {
System.out.printf("第%d条链表的数据为\n",i+1);
linkedListArray[i].list();
}
}
/**
* 散列函数,取模法,将结点根据id对数组大小取模,来决定该结点加入到哪一个链表
*
* @param id
* @return
*/
private int hashFunction(int id) {
return id % linkedListArray.length;
}
}
/***
* 结点
*
* @author laowa
*
*/
class Node {
int id;
String name;
String nickName;
Node next;
public Node(int id, String name, String nickName) {
this.id = id;
this.name = name;
this.nickName = nickName;
this.next = null;
}
public Node(int id, String name, String nickName, Node next) {
this.id = id;
this.name = name;
this.nickName = nickName;
this.next = next;
}
@Override
public String toString() {
return "id=" + id + "\tname=" + name + "\tnickName=" + nickName;
}
}
/***
* 单链表
*
* @author laowa
*
*/
class SingleLinkedList {
Node head = new Node(0, null, null);
/**
* 添加结点
*
* @param node
* 新节点
*/
public void add(Node node) {
Node helper = head;
while (helper.next != null) {
helper = helper.next;
}
helper.next = node;
}
/**
* 通过id删除结点
*
* @param id
* 待删除的结点的id
*/
public void delete(int id) {
Node helper = head;
while (helper.next != null && helper.next.id != id) {
helper = helper.next;
}
if (helper.next == null) {
System.out.println("该节点不存在");
} else {
helper.next = helper.next.next;
}
}
/**
* 修改结点
*
* @param node
* 新的结点信息
*/
public void update(Node node) {
Node helper = head;
while (helper.next != null && helper.next.id != node.id) {
helper = helper.next;
}
if (helper.next == null) {
System.out.println("该节点不存在");
} else {
node.next = helper.next.next;
helper.next = node;
}
}
/**
* 通过id获取结点
* @param id 需要获取的结点的id
*/
public Node get(int id) {
Node helper = head;
while(helper.next!=null&&helper.next.id!=id) {
helper = helper.next;
}
if(helper.next==null) {
throw new RuntimeException("该结点不存在");
}
return helper.next;
}
/**
* 打印链表
*/
public void list() {
if (head.next == null) {
System.out.println("空");
}
Node helper = head.next;
while (helper != null) {
System.out.println(helper);
helper = helper.next;
}
}
}