数据结构四之符号表

符号表

符号表的概念

符号表是存储键及对应值的数据结构,其最主要的目的是将一个键和一个值关联起来,符号表能够将存储的数据元素是一个键和一个值共同组成键值对数据,我们可以根据键来查找对应的值。符号表中,键必须是唯一的,而值可以不唯一。日常生活中,根据关键字百度查找资料,根据目录查找书籍内容,都是符号表使用的体现。

符号表API

类名SymbolTable<Key,Value>
构造方法 public SymbolTable()
成员变量

    /**
     * 头结点
     */
    private Node head;

    /**
     * 结点个数
     */
    private int size;

成员方法/**
     * 结点个数
     */
    public int size() ;
    
    /**
     * 插入元素
     */
    public void put(Key key, Value value) ;
    
    /**
     * 删除元素
     */
    public void delete(Key key);

符号表实现

/**
 * 符号表实现
 */
public class SymbolTable<Key,Value> {

    /**
     * 头结点
     */
    private Node head;

    /**
     * 结点个数
     */
    private int size;

    /**
     * 构造函数
     */
    public SymbolTable() {
        this.head = new Node(null, null, null);
        this.size = 0;
    }

    /**
     * 结点个数
     */
    public int size() {
        return this.size;
    }

    /**
     * 插入元素
     */
    public void put(Key key, Value value) {
        Node node = this.head;

        while (node.next != null) {
            node = node.next;

            if (node.key.equals(key)) {
                node.value = value;
                return;
            }
        }

        Node oldFirst = this.head.next;
        Node newFirst = new Node(key, value, oldFirst);
        head.next = newFirst;
        this.size++;
    }

    /**
     * 删除元素
     */
    public void delete(Key key) {
        Node node = this.head;

        while (node.next != null) {


            if (node.next.key.equals(key)) {
                node.next = node.next.next;
                this.size--;
                return;
            }

            node = node.next;
        }
    }

    /**
     * 获取元素
     */
    public Value get(Key key){
        Node node = this.head;

        while (node.next != null) {
            node = node.next;

            if (node.key.equals(key)) {
                return node.value;
            }
        }

        return null;
    }

    /**
     * 结点
     */
    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;
        }

        public Key getKey() {
            return key;
        }

        public void setKey(Key key) {
            this.key = key;
        }

        public Value getValue() {
            return value;
        }

        public void setValue(Value value) {
            this.value = value;
        }

        public Node getNext() {
            return next;
        }

        public void setNext(Node next) {
            this.next = next;
        }
    }
}

有序符号表

有序符号表概念

上述的符号表,插入元素时没有根据key进行排序,是无序的。

  日常使用中,会出现需要根据key进行排序的需求,实现思路是在put方法时,去遍历比较key和当前结点的key大小,当key比当前结点key大时则继续往下走,走到发现没有比key大的当前结点时

  比较两个key是否相等,是则替换value,不是则新增结点,并实现连接。

有序符号表API

类名OrderSymbolTable<Key extends Comparable<Key>,Value>
构造方法public OrderSymbolTable()
成员变量

  /**
     * 头结点
     */
    private Node head;

    /**
     * 结点个数
     */
    private int size;

成员方法/**
     * 结点个数
     */
    public int size() ;
    
    /**
     * 插入元素
     */
    public void put(Key key, Value value) ;
    
    /**
     * 删除元素
     */
    public void delete(Key key);

有序符号表实现

/**
 * 有序符号表实现
 */
public class OrderSymbolTable<Key extends Comparable<Key>,Value> {

    /**
     * 头结点
     */
    private Node head;

    /**
     * 结点个数
     */
    private int size;

    /**
     * 构造函数
     */
    public OrderSymbolTable() {
        this.head = new Node(null, null, null);
        this.size = 0;
    }

    /**
     * 结点个数
     */
    public int size() {
        return this.size;
    }

    /**
     * 插入元素
     */
    public void put(Key key, Value value) {
        Node current = this.head.next;
        Node pre = this.head;

        while (current != null && key.compareTo(current.key) > 0) {
           pre = current;
           current = current.next;
        }

        if(current != null && current.key.compareTo(key) == 0){
            current.value = value;
            return;
        }

        Node newFirst = new Node(key, value, current);
        pre.next = newFirst;
        this.size++;
    }

    /**
     * 删除元素
     */
    public void delete(Key key) {
        Node node = this.head;

        while (node.next != null) {


            if (node.next.key.equals(key)) {
                node.next = node.next.next;
                this.size--;
                return;
            }

            node = node.next;
        }
    }

    /**
     * 获取元素
     */
    public Value get(Key key){
        Node node = this.head;

        while (node.next != null) {
            node = node.next;

            if (node.key.equals(key)) {
                return node.value;
            }
        }

        return null;
    }

    /**
     * 结点
     */
    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;
        }

        public Key getKey() {
            return key;
        }

        public void setKey(Key key) {
            this.key = key;
        }

        public Value getValue() {
            return value;
        }

        public void setValue(Value value) {
            this.value = value;
        }

        public Node getNext() {
            return next;
        }

        public void setNext(Node next) {
            this.next = next;
        }
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值