简单符号表功能
- 获取符号表中存储的键值对数据个数 size()
- 往符号表中插入键值对数据 put()
- 删除符号表指定key对应的结点并返回该结点存储的值 delete()
- 获取符号表中指定key对应的value并返回 get()
无序符号表
public class SymbolTable<Key,Value> {
//记录首结点
private Node head;
//记录当前符号表存储的键值对数据个数
private int N;
//定义内部的结点类Node
private class Node{
//Node中存储的键值对数据的键
public Key key;
//该键对应的值
public Value value;
//该节点指向的下一个结点
public Node next;
//内部Node类构造方法
public Node(Key key,Value value,Node next){
//初始化各个参数
this.key=key;
this.value=value;
this.next=next;
}
}
//SymbolTable构造方法
public SymbolTable(){
this.head=new Node(null,null,null);
this.N=0;
}
//获取符号表中键值对个数
public int size(){
return N;
}
//在符号表中插入键值对数据
public void put(Key key,Value value){
//存储键值对数据 先判断该符号表中是否存在键为key的键值对数据
Node n=head;
while (n.next!=null){
n=n.next;
if(key.equals(n.key)){
//存在键为key的键值对数据,覆盖value即可 键值对个数不变
n.value=value;
//直接结束该方法
return;
}
}
//循环到尾结点 没有该key对应的键值对数据,创建新结点存储该键值对 并且将该结点插入到链表的头部,新结点的next指向原先头结点指向的Node=head.next
Node newNode=new Node(key,value,head.next);
//头结点的next指向该新增节点
head.next=newNode;
//存储键值对个数+1
N++;
}
//删除符号表中键为key的键值对数据,并返回该键对应的值
public Value delete(Key key){
//创建n结点 将head赋值给该节点
Node n=head;
//n节点的前一个结点
Node pre=null;
//首先遍历该链表是否存在键为key的结点
while (n.next!=null){
pre=n;
n=n.next;
if(key.equals(n.key)){
//链表中存在键为key的结点,删除该结点
//此时n结点的前一个结点pre的next指向n的下一个结点
pre.next=n.next;
//键值对个数-1
N--;
return n.value;
}
}
//不存在键位key的键值对数据 直接返回null
return null;
}
//获取符号表中key对应的值
public Value get(Key key){
Node n=head;
//遍历链表
while (n.next!=null){
n=n.next;
if (key.equals(n.key)){
//存在键为key的结点 返回该结点的value
return n.value;
}
}
//不存在键为key的结点 返回null
return null;
}
}
有序符号表
public class OrderSymbolTable<Key extends Comparable<Key>,Value> {
//记录首结点
private Node head;
//记录当前符号表存储的键值对数据个数
private int N;
//定义内部的结点类Node
private class Node{
//Node中存储的键值对数据的键
public Key key;
//该键对应的值
public Value value;
//该节点指向的下一个结点
public Node next;
//内部Node类构造方法
public Node(Key key,Value value,Node next){
//初始化各个参数
this.key=key;
this.value=value;
this.next=next;
}
}
//SymbolTable构造方法
public OrderSymbolTable(){
this.head=new Node(null,null,null);
this.N=0;
}
//获取符号表中键值对个数
public int size(){
return N;
}
//在符号表中插入键值对数据,依照key对符号表的中的键值对数据进行排序
public void put(Key key,Value value){
//定义两个Node变量记录当前结点与当前结点的上一个结点
Node curr=head.next;
Node pre=head;
//遍历查找链表中是否存在键值大于等于key的结点
while (curr!=null && key.compareTo(curr.key)>0){
//未到尾结点 并且 key比遍历的结点存储的key要大
pre=curr;
curr=curr.next;
}
/** 循环结束的几种情况
* 1.当curr为尾结点时条件key.compareTo(curr.key)>0依旧成立继续遍历下一次遍历curr=null,此时key比链表中所有结点存储的键都大 pre成为尾结点
* 2.结点存储的键>=key
*/
// 判断
if(curr!=null && key.compareTo(curr.key)==0){
//存在结点存储的键与key相同 修改该结点的值为value 即可
curr.value=value;
return;
}
/**
* 下段代码的两种情况
* 1.curr不为null ,curr存储的键大于key,创建新结点存储键值对数据 插入curr前面 next指向curr pre指向新结点
* 2.curr为null key比所有结点中存储的键都要大,pre为尾结点 curr为尾结点指向的null
*/
//创建新结点存储键值,且新结点为新的尾结点
Node newNode=new Node(key,value,curr);
//pre的next指向该新结点
pre.next=newNode;
//元素个数+1
N++;
}
//删除符号表中键为key的键值对数据,并返回该键对应的值
public Value delete(Key key){
//创建n结点 将head赋值给该节点
Node n=head;
//n节点的前一个结点
Node pre=null;
//首先遍历该链表是否存在键为key的结点
while (n.next!=null){
pre=n;
n=n.next;
if(key.equals(n.key)){
//链表中存在键为key的结点,删除该结点
//此时n结点的前一个结点pre的next指向n的下一个结点
pre.next=n.next;
//键值对个数-1
N--;
return n.value;
}
}
//不存在键位key的键值对数据 直接返回null
return null;
}
//获取符号表中key对应的值
public Value get(Key key){
Node n=head;
//遍历链表
while (n.next!=null){
n=n.next;
if (key.equals(n.key)){
//存在键为key的结点 返回该结点的value
return n.value;
}
}
//不存在键为key的结点 返回null
return null;
}
}