0 概述
互联网时代能够使我们访问海量的信息,高效检索这些信息的能力就显得非常重要。使用符号表(也称为字典)这个词开描述抽象的表格,我们将会将信息的存储在其中,然后按照指定的键来搜索这些信息。
1 符号表简介
符号表最主要的目的就是将一个键和一个值联系起来。用例能够将一个键值对插入符号表中以及能通过相应的键获取到对应的值。
2 符号表接口定义
值得强调是:如果使用Key不是java 自定义类型的话必须要覆写equals()方法
import java.util.Iterator;
/**
* Created by hsc on 17/6/13.
*/
public interface SymbolTable<Key,Value> {
/**
* 将键值对写入符号表
* @param key 键
* @param value 值
*/
Value put(Key key,Value value);
/**
* 获取key的对应值,如果键不存在则返回null
* @param key
* @return Value
*/
Value get(Key key);
/**
* 删除键以及对应的值
* @param key
*/
Value delete(Key key);
/**
* 是否包含了这个键
* @param key
*/
boolean containsKey(Key key);
/**
* 是否为空
* @return
*/
boolean isEmpty();
/**
* 表中键值对数量
* @return
*/
int size();
/**
* 表中键的迭代器
* @return
*/
Iterator<Key> keys();
}
3 链表实现符号表
采用链表实现符号表:查询、插入、删除最坏时间复杂度为O(n)
import java.util.*;
/**
* Created by hsc on 17/6/14.
* 采用链表方式实现 相关操作是线程不安全的
*
*/
public class LinkedListedST<Key, Value> implements SymbolTable<Key, Value> {
/**
* size 大小
*/
private int size;
/**
* 链表节点
*/
private Node head;
/**
* 链表节点
*/
private 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;
}
}
@Override
public Value put(Key key, Value value) {
for (Node node = head; node != null; node = node.next) {
if (Objects.equals(key, node.key)) {
node.value = value;
return value;
}
}
//头插入法
head = new Node(key, value, head);
size++;
return value;
}
@Override
public Value get(Key key) {
for (Node node = head; node != null; node = node.next) {
if (Objects.equals(key, node.key)) {
return node.value;
}
}
return null;
}
@Override
public Value delete(Key key) {
Node pre = head;
for (Node node = head; node != null; node = node.next) {
if (Objects.equals(key, node.key)) {
pre.next = node.next;
//如果是头节点
if (node == head) {
head = node.next;
}
size--;
return node.value;
}
pre = node;
}
return null;
}
@Override
public boolean containsKey(Key key) {
for (Node node = head; node != null; node = node.next) {
if (Objects.equals(key, node.key)) {
return true;
}
}
return false;
}
@Override
public boolean isEmpty() {
return size() == 0;
}
@Override
public int size() {
return this.size;
}
@Override
public Iterator<Key> keys() {
List<Key> list = new ArrayList<>(size);
for (Node node = head; node != null; node = node.next) {
list.add(node.key);
}
return list.iterator();
}
}
测试程序:
import java.util.Iterator;
/**
* Created by hsc on 17/6/14.
*/
public class TestMain {
public static void main(String[] args) {
SymbolTable<String, String> st = new LinkedListedST<>();
st.put(null, "null");
st.put(null, null); //测试覆盖
st.put("computer", "电脑");
st.put("SymbolTable", "符号表");
System.out.println("containsKey:null "+st.containsKey(null));
System.out.println("删除"+st.delete("computer"));
System.out.println(st.isEmpty());
Iterator<String> iterator = st.keys();
while (iterator.hasNext()) {
System.out.println(st.get(iterator.next()));
}
}
}
参考文献[1] 算法(第四版),Robert Sedgewick 著