数据结构与算法--符号表

314 阅读2分钟

符号表

基础知识

定义

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

图例

image.png

特点

键具有唯一性

代码实现

符号表的API实现

  1. 结点类

image.png

  1. 符号表

image.png

  1. 代码实现
package com.study.symboltable;


public class SymbolTableAPI<Key,Value>{
    private Node head;
    private int N;

    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 SymbolTableAPI() {
        this.head = new Node(null,null,null);
        this.N = 0;
    }
    // 得到符号表的大小
    public int size(){
        return N;
    }
    // 得到key对应的value
    public Value get(Key key){
        Node n = head;
        while (n.next!=null){
            if (n.next.key.equals(key)){
                return n.next.value;
            }
            n = n.next;
        }
        return null;
    }
    // 放入 <key,value>
    public void put(Key key,Value value){
        Node n = head;
        while (n.next!=null){
            if (n.next.key.equals(key)){
                n.next.value = value;
                return;
            }
            n = n.next;
        }
        Node newNode = new Node(key, value, null);
        Node first = head.next;
        head.next = newNode;
        newNode.next=first;
        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;
                N--;
                return;
            }
            n = n.next;
        }
        System.out.println("symbolTable has no this key");
    }

}

  1. 测试
package com.study.symboltable;

public class SymbolTableTest {
    public static void main(String[] args) {
        SymbolTableAPI<Integer, String> st = new SymbolTableAPI<>();
        st.put(1,"a");
        st.put(2,"b");
        st.put(3,"c");
        st.put(5,"e");
        st.put(4,"d");
        st.put(3,"f");
        System.out.println(st.size());
        System.out.println(st.get(3));
        st.delete(1);
        System.out.println(st.size());
    }
}

  1. 运行结果

image.png

再查看一下插入的顺序

  • 插入st.put(4,"d");

image.png

  • 插入st.put(4,"d");

image.png

通过运行结果可以发现,插入的顺序是乱的,这时候,我们就可以更新一下API,实现顺序的排序,这就是有序符号表

  1. 改进代码(只需要改进插入方法就行)
    public void put(Key key, Value value) {
        // 定义两个Node变量,分别记录当前结点和当前结点的下一个结点
        Node currentNode = head.next;
        Node preNode = head;
        // 遍历符号表,比较key的大小,找到插入值的位置(通过compareTo)
        // 遍历完的时候,就是找到了值需要插入的地方
        while (currentNode != null && key.compareTo(currentNode.key) > 0) {
            // 交换当前结点和前一个结点
            preNode = currentNode;
            currentNode = currentNode.next;
        }

        // 当前key和插入的key相同,更换value
        if (currentNode != null && key.compareTo(currentNode.key) == 0) {
            currentNode.value = value;
            return;
        }
        // 当前key和插入的key不同,插入<key,value>
        // 创建的<key,value>指向currentNode,preNode指向新节点<key,value>
        preNode.next = new Node(key, value, currentNode);
        // 元素个数+1
        N++;
    }
  1. 测试
package com.study.symboltable;

public class orderSymbolTableTest {
    public static void main(String[] args) {
        orderSymbolTableAPI<Integer, String> ost = new orderSymbolTableAPI<>();
        ost.put(1,"a");
        ost.put(2,"b");
        ost.put(4,"d");
        ost.put(5,"e");
        ost.put(3,"c");

    }
}

  1. 结果:
  • 没插入ost.put(3,"c");的时候

image.png

  • 插入ost.put(3,"c");的时候

image.png

解决问题~