自定义代码以链表实现简单无序符号表与有序符号表

简单符号表功能

  1. 获取符号表中存储的键值对数据个数 size()
  2. 往符号表中插入键值对数据 put()
  3. 删除符号表指定key对应的结点并返回该结点存储的值 delete()
  4. 获取符号表中指定key对应的value并返回 get()
无序符号表
public class SymbolTable<Key,Value> {

    //记录首结点
    private Node head;

    //记录当前符号表存储的键值对数据个数
    private int N;

    //定义内部的结点类Node
    private class Node{
        //Node中存储的键值对数据的键
        public Key key;

        //该键对应的值
        public Value value;

        //该节点指向的下一个结点
        public Node next;

        //内部Node类构造方法
        public Node(Key key,Value value,Node next){
            //初始化各个参数
            this.key=key;
            this.value=value;
            this.next=next;
        }
    }

    //SymbolTable构造方法
    public SymbolTable(){
        this.head=new Node(null,null,null);
        this.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(key.equals(n.key)){
                //存在键为key的键值对数据,覆盖value即可 键值对个数不变
                n.value=value;
                //直接结束该方法
                return;
            }
        }
        //循环到尾结点 没有该key对应的键值对数据,创建新结点存储该键值对 并且将该结点插入到链表的头部,新结点的next指向原先头结点指向的Node=head.next
        Node newNode=new Node(key,value,head.next);
        //头结点的next指向该新增节点
        head.next=newNode;
        //存储键值对个数+1
        N++;
    }

    //删除符号表中键为key的键值对数据,并返回该键对应的值
    public Value delete(Key key){

        //创建n结点 将head赋值给该节点
        Node n=head;
        //n节点的前一个结点
        Node pre=null;
        //首先遍历该链表是否存在键为key的结点
        while (n.next!=null){
            pre=n;
            n=n.next;
            if(key.equals(n.key)){
                //链表中存在键为key的结点,删除该结点
                //此时n结点的前一个结点pre的next指向n的下一个结点
                pre.next=n.next;
                //键值对个数-1
                N--;
                return n.value;
            }
        }
        //不存在键位key的键值对数据 直接返回null
        return null;
    }

    //获取符号表中key对应的值
    public Value get(Key key){

        Node n=head;
        //遍历链表
        while (n.next!=null){
            n=n.next;
            if (key.equals(n.key)){
                //存在键为key的结点 返回该结点的value
                return n.value;
            }
        }
        //不存在键为key的结点 返回null
        return null;
    }

}
有序符号表
public class OrderSymbolTable<Key extends Comparable<Key>,Value> {

    //记录首结点
    private Node head;

    //记录当前符号表存储的键值对数据个数
    private int N;

    //定义内部的结点类Node
    private class Node{
        //Node中存储的键值对数据的键
        public Key key;

        //该键对应的值
        public Value value;

        //该节点指向的下一个结点
        public Node next;

        //内部Node类构造方法
        public Node(Key key,Value value,Node next){
            //初始化各个参数
            this.key=key;
            this.value=value;
            this.next=next;
        }
    }

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

    //获取符号表中键值对个数
    public int size(){
        return N;
    }

    //在符号表中插入键值对数据,依照key对符号表的中的键值对数据进行排序
    public void put(Key key,Value value){

        //定义两个Node变量记录当前结点与当前结点的上一个结点
        Node curr=head.next;
        Node pre=head;
        //遍历查找链表中是否存在键值大于等于key的结点
        while (curr!=null && key.compareTo(curr.key)>0){
            //未到尾结点 并且 key比遍历的结点存储的key要大
            pre=curr;
            curr=curr.next;
        }
        /** 循环结束的几种情况
         *  1.当curr为尾结点时条件key.compareTo(curr.key)>0依旧成立继续遍历下一次遍历curr=null,此时key比链表中所有结点存储的键都大 pre成为尾结点
         *  2.结点存储的键>=key
         */
        // 判断
        if(curr!=null && key.compareTo(curr.key)==0){
            //存在结点存储的键与key相同 修改该结点的值为value 即可
            curr.value=value;
            return;
        }

        /**
         * 下段代码的两种情况
         * 1.curr不为null ,curr存储的键大于key,创建新结点存储键值对数据 插入curr前面 next指向curr pre指向新结点
         * 2.curr为null key比所有结点中存储的键都要大,pre为尾结点  curr为尾结点指向的null
         */
        //创建新结点存储键值,且新结点为新的尾结点
        Node newNode=new Node(key,value,curr);
        //pre的next指向该新结点
        pre.next=newNode;
        //元素个数+1
        N++;

    }

    //删除符号表中键为key的键值对数据,并返回该键对应的值
    public Value delete(Key key){

        //创建n结点 将head赋值给该节点
        Node n=head;
        //n节点的前一个结点
        Node pre=null;
        //首先遍历该链表是否存在键为key的结点
        while (n.next!=null){
            pre=n;
            n=n.next;
            if(key.equals(n.key)){
                //链表中存在键为key的结点,删除该结点
                //此时n结点的前一个结点pre的next指向n的下一个结点
                pre.next=n.next;
                //键值对个数-1
                N--;
                return n.value;
            }
        }
        //不存在键位key的键值对数据 直接返回null
        return null;
    }

    //获取符号表中key对应的值
    public Value get(Key key){

        Node n=head;
        //遍历链表
        while (n.next!=null){
            n=n.next;
            if (key.equals(n.key)){
                //存在键为key的结点 返回该结点的value
                return n.value;
            }
        }
        //不存在键为key的结点 返回null
        return null;
    }

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值