符号表
符号表最主要的目的是将一个键和一个值联系起来。如下图所示:
下边我们用链表的形式来创建符号表类。
插入方法
public void put(key key,value value){
//符号表中已经存在键为key的键值对,找到并替换值为value即可
Node n=head;
while (n.next!=null){
n=n.next;
//判断n结点的键是否为key,如果是,则替换n结点的值
if (n.key.equals(key)){
n.value=value;
return;
}
}
//符号表中不存在键为key的键值对,只需创建新的结点,把新结点放在链表的头部即可
Node newNode = new Node(key, value, null);
Node oldfirst = head.next;
newNode.next=oldfirst;
head.next=newNode;
//元素个数加一
N++;
}
删除方法
public void delete(key key){
//找到键为key的键值对,把该结点从链表中删除
Node n=head;
while (n.next!=null) {
//判断n结点的下一个结点是否为key,如果是,就删除
if (n.next.key.equals(key)) {
n.next = n.next.next;
N--;
return;
}
//变换n
n = n.next;
}
}
查找方法
public value get(key key){
Node n=head;
while (n.next!=null){
n=n.next;
if (n.key.equals(key)){
return n.value;
}
}
return null;
}
完整代码
public class SymbolTable<key,value> {
private Node head;
private int N;
public class Node {
public value value;
public Node next;
public key key;
public Node(key key, value value, Node next) {
this.key = key;
this.value = value;
this.next = next;
}
}
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的键值对,找到并替换值为value即可
Node n=head;
while (n.next!=null){
n=n.next;
//判断n结点的键是否为key,如果是,则替换n结点的值
if (n.key.equals(key)){
n.value=value;
return;
}
}
//符号表中不存在键为key的键值对,只需创建新的结点,把新结点放在链表的头部即可
Node newNode = new Node(key, value, null);
Node oldfirst = head.next;
newNode.next=oldfirst;
head.next=newNode;
//元素个数加一
N++;
}
//删除键值对
public void delete(key key){
//找到键为key的键值对,把该结点从链表中删除
Node n=head;
while (n.next!=null) {
//判断n结点的下一个结点是否为key,如果是,就删除
if (n.next.key.equals(key)) {
n.next = n.next.next;
N--;
return;
}
//变换n
n = n.next;
}
}
//从符号表中获取key对应的值
public value get(key key){
Node n=head;
while (n.next!=null){
n=n.next;
if (n.key.equals(key)){
return n.value;
}
}
return null;
}
}
上述符号表存在一个问题,即插入元素时总是插入到首位置,没有进行排序,下面对其进行改进
能进行排序的插入方法
public void put(key key,value value){
//定义两个Node变量,记录当前结点和上一个节点
Node cur=head.next;
Node pre=head;
while (cur!=null && key.compareTo(cur.key)>0){
//变换当前结点和前一个结点即可
pre=cur;
cur=cur.next;
}
//如果键一样,则替换
if (cur!=null && key.compareTo(cur.key)==0){
cur.value=value;
return;
}
//如果键不一样,把新结点插入到cur之前
Node newNode = new Node(key, value, cur);
pre.next=newNode;
//元素个数+1
N++;
}
完整代码
public class OrderSymbolTable<key extends Comparable<key>,value> {
private Node head;
private int N;
public class Node {
public value value;
public Node next;
public key key;
public Node(key key, value value, Node next) {
this.key = key;
this.value = value;
this.next = next;
}
}
public OrderSymbolTable(){
this.head=new Node(null,null,null);
this.N=0;
}
public int size(){
return N;
}
//向符号表中删除键值对
public void delete(key key){
//找到键为key的键值对,把该结点从链表中删除
Node n=head;
while (n.next!=null) {
//判断n结点的下一个结点是否为key,如果是,就删除
if (n.next.key.equals(key)) {
n.next = n.next.next;
N--;
return;
}
//变换n
n = n.next;
}
}
//插入键值对
public void put(key key,value value){
//定义两个Node变量,记录当前结点和上一个节点
Node cur=head.next;
Node pre=head;
while (cur!=null && key.compareTo(cur.key)>0){
//变换当前结点和前一个结点即可
pre=cur;
cur=cur.next;
}
//如果键一样,则替换
if (cur!=null && key.compareTo(cur.key)==0){
cur.value=value;
return;
}
//如果键不一样,把新结点插入到cur之前
Node newNode = new Node(key, value, cur);
pre.next=newNode;
//元素个数+1
N++;
}
//从符号表中获取key对应的值
public value get(key key){
Node n=head;
while (n.next!=null){
n=n.next;
if (n.key.equals(key)){
return n.value;
}
}
return null;
}
}
b站详细讲解网址:http://yun.itheima.com/course/639.html