一. 无序符号表
符号表最主要的目的就是将一个键和值联系起来[1],使得可以通过键(Key)直接找到相对应的值,本文通过链表[2]实现无需符号表,首先需要定义结点内部类,这里的结点内部类应当包括Key,Value以及指向下一个结点的next。具体java代码如下:
public class Node{
private Key key;
private Value value;
private Node next;
public Node(Key key,Value value,Node next){
this.key=key;
this.value=value;
this.next=next;
}
}
put方法:将键值对存入链表中。如果输入的键(Key)已经存在,则更新值(Value)为当前传入的值,如果输入的是新的键(Key)则添加到链表末尾。同时需要将记录链表中元素个数的N进行加1操作。java实现如下:
public void put(Key key,Value value){
Node node=head;
while (node.next!=null){
node=node.next;
if (node.key==key){
node.value=value;
N++;
return;
}
}
Node newNode=new Node(key,value,null);
node.next=newNode;
N++;
}
get方法:获取键Key对应的值,如果key不存在则返回null。
public Value get(Key key){
Node node=head;
while (node.next!=null){
node=node.next;
if (node.key==key){
return node.value;
}
}
return null;
}
delete方法:从表中删除键key对应的结点。循环遍历结点,找到输入key值相对应的结点,将该结点前一个结点的next指向其后一个结点实现删除。java实现如下:
public void delete(Key key){
Node node=head;
while (node.next!=null){
if (node.next.key==key){
node.next=node.next.next;
N--;
return;
}
node=node.next;
}
}
contains方法:判断键Key是否在表中
public boolean contains(Key key){
Node node =head;
while (node.next!=null){
if (node.key == key) {
return true;
}
node = node.next;
}
return false;
}
迭代获取链表中所有键的集合
@Override
public Iterator<Key> iterator() {
return new SIterator();
}
public class SIterator implements Iterator{
Node node;
public SIterator(){
node=head;
}
@Override
public boolean hasNext() {
return node.next!=null;
}
@Override
public Object next() {
node=node.next;
return node.key;
}
}
完整代码:
/**
* 无序符号表的实现
* @param <Key>
* @param <Value>
*/
public class SymbolTable<Key,Value> implements Iterable<Key>{
//定义头部节点
private Node head;
//定义元素个数
private int N;
public SymbolTable(){
head=new Node(null,null,null);
N=0;
}
@Override
public Iterator<Key> iterator() {
return new SIterator();
}
public class SIterator implements Iterator{
Node node;
public SIterator(){
node=head;
}
@Override
public boolean hasNext() {
return node.next!=null;
}
@Override
public Object next() {
node=node.next;
return node.key;
}
}
public class Node{
private Key key;
private Value value;
private Node next;
public Node(Key key,Value value,Node next){
this.key=key;
this.value=value;
this.next=next;
}
}
public int size(){
return N;
}
public void put(Key key,Value value){
Node node=head;
while (node.next!=null){
node=node.next;
if (node.key==key){
node.value=value;
N++;
return;
}
}
Node newNode=new Node(key,value,null);
node.next=newNode;
N++;
}
public Value get(Key key){
Node node=head;
while (node.next!=null){
node=node.next;
if (node.key==key){
return node.value;
}
}
return null;
}
public void delete(Key key){
Node node=head;
while (node.next!=null){
if (node.next.key==key){
node.next=node.next.next;
N--;
return;
}
node=node.next;
}
}
public boolean contains(Key key){
Node node =head;
while (node.next!=null){
if (node.key == key) {
return true;
}
node = node.next;
}
return false;
}
public boolean isEmpty(){
return N==0;
}
}
二. 有序符号表
有序符号表同无序符号表的区别是有序符号表的key需要按照大小来排列,其他方法基本类似,最大的区别在于put方法,(注意:首先在定义类时需要使Key继承Comparable<Key>使其能比较大小Key的大小)。这里的设计是采用key从大到小排列的方式进行,java代码如下:
public void put(Key key,Value value){
Node node=head;
// Node pre=head;
// while (node!=null && node.key.compareTo(key)>0){
// pre.next=
// }
while (node.next!=null){
if (node.next.key==key){
node.next.value=value;
N++;
return;
}else if(node.next.key.compareTo(key)>0) {
Node newNode=new Node(key,value,null);
Node temp=node.next;
node.next=newNode;
newNode.next=temp;
N++;
return;
}
node=node.next;
}
Node newNode=new Node(key,value,null);
node.next=newNode;
N++;
}
完整代码:
/**
* 有序符号表的实现
* @param <Key>
* @param <Value>
*/
public class OrderSymbolTable<Key extends Comparable<Key>,Value> implements Iterable<Value>{
//定义头部节点
private Node head;
//定义元素个数
private int N;
public OrderSymbolTable(){
head=new Node(null,null,null);
N=0;
}
@Override
public Iterator<Value> iterator() {
return new SIterator();
}
public class SIterator implements Iterator{
Node node;
public SIterator(){
node=head;
}
@Override
public boolean hasNext() {
return node.next!=null;
}
@Override
public Object next() {
node=node.next;
return node.value;
}
}
public class Node{
private Key key;
private Value value;
private Node next;
public Node(Key key,Value value,Node next){
this.key=key;
this.value=value;
this.next=next;
}
}
public int size(){
return N;
}
public void put(Key key,Value value){
Node node=head;
// Node pre=head;
// while (node!=null && node.key.compareTo(key)>0){
// pre.next=
// }
while (node.next!=null){
if (node.next.key==key){
node.next.value=value;
N++;
return;
}else if(node.next.key.compareTo(key)>0) {
Node newNode=new Node(key,value,null);
Node temp=node.next;
node.next=newNode;
newNode.next=temp;
N++;
return;
}
node=node.next;
}
Node newNode=new Node(key,value,null);
node.next=newNode;
N++;
}
public Value get(Key key){
Node node=head;
while (node.next!=null){
node=node.next;
if (node.key==key){
return node.value;
}
}
return null;
}
public void delete(Key key){
Node node=head;
while (node.next!=null){
if (node.next.key==key){
node.next=node.next.next;
N--;
return;
}
node=node.next;
}
}
}
参考
- ^算法4
- ^https://zhuanlan.zhihu.com/p/148785153