符号表-java语言版

660 阅读2分钟

符号表最主要的目的就是将一个键和一个值联系起来,符号表能够将存储的数据元素是一个键和一个值共同组成的 键值对数据,我们可以根据键来查找对应的值。

符号表.png

符号表中,键具有唯一性。 符号表在实际生活中的使用场景是非常广泛的,见下表:

符号表应用.png

-- API设计:

符号表API.png

-- 代码:

public class SymbolTable<Key,Value> {
    // 记录首结点
    private Node head;
    // 记录符号表中元素的个数
    private int N;

    // 构造方法
    public SymbolTable() {
        head = new Node(null,null,null);
        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(n.key.equals(key)) {
                // 如果当前结点的key等于要插入key,直接将值覆盖
                n.value = value;
            }
        }

        // 如果没有与要插入的key相等,构建新结点,新结点的下一个指向为head.next
        Node newNode = new Node(key,value,head.next);
        head.next = newNode;
        // 个数+1
        N++;
    }

    // 删除符号表中键为key的键值对
    public void delete(Key key) {
        Node n = head;
        // 遍历链表
        while (n.next != null) {
            // 当前结点的下一个结点为要删除的元素
            if(n.next.key.equals(key)) {
                n.next = n.next.next;
                // 个数-1
                N--;
                return;
            }
            n = n.next;
        }
    }

    // 从符号表中获取key对应的值
    public Value get(Key key) {
        Node n = head;
        // 遍历链表找到key对应的值
        while (n.next != null) {
            n = n.next;
            if(n.key.equals(key)) {
                return n.value;
            }
        }
        return null;
    }

    // 结点类
    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 class SymbolTableTest {
    public static void main(String[] args) throws Exception {
        SymbolTable<Integer, String> st = new SymbolTable<>();
        st.put(1, "张三");
        st.put(3, "李四");
        st.put(5, "王五");
        System.out.println(st.size());
        st.put(1, "老三");

        System.out.println(st.get(1));
        System.out.println(st.size());
        st.delete(1);
        System.out.println(st.size());
    }
}

-- 运行效果图:

运行效果图.png


-- 有序符号表:

刚才实现的符号表,我们可以称之为无序符号表,因为在插入的时候,并没有考虑键值对的顺序,而在实际生活 中,有时候我们需要根据键的大小进行排序,插入数据时要考虑顺序,那么接下来我们就实现一下有序符号表。

-- 代码:

/**
 * 有序符号表
 */
public class OrderSymbolTable<Key extends Comparable<Key>,Value> {
    // 记录首结点
    private Node head;
    // 记录符号表中元素的个数
    private int N;

    // 构造方法
    public OrderSymbolTable() {
        head = new Node(null,null,null);
        N = 0;
    }

    // 获取符号表中元素的个数
    public int size() {
        return N;
    }

    // 往符号表中插入键值对
    public void put(Key key,Value value) {
        // 当前结点
        Node curr = head.next;
        // 上一个结点
        Node pre = head;

        // 如果key大于当前结点key,则一直寻找下去
        while (curr != null && key.compareTo(curr.key) > 0) {
            pre = curr;
            curr = curr.next;
        }
        // 如果当前结点的key和要插入的key一样,则替换
        if(curr != null && curr.key.compareTo(key) == 0) {
            curr.value = value;
        }
        // 如果没有找到相同的key,把新结点插入到curr之前
        Node newNode = new Node(key,value,curr);
        pre.next = newNode;
    }

    // 删除符号表中键为key的键值对
    public void delete(Key key) {
        Node n = head;
        // 遍历符号表
        while (n.next != null) {
            if(n.next.key.equals(key)) {
                // 当前结点的下一个结点为要删除的结点
                n.next = n.next.next;
                // 个数-1
                N--;
                return;
            }
            n = n.next;
        }
    }

    // 从符号表中获取key对应的值
    public Value get(Key key) {
       Node n = head;
        // 遍历链表找到key对应的值
        while (n.next != null) {
            n = n.next;
            if(n.key.equals(key)) {
                return n.value;
            }
        }
        return null;
    }
    // 结点类
    class Node {
        // 存储Key
        private Key key;
        // 存储Value
        private Value value;
        // 下一个指向
        private Node next;

        // 构造方法
        public Node(Key key, Value value, Node next) {
            this.key = key;
            this.value = value;
            this.next = next;
        }
    }
}

@ 以上内容属于个人笔记