线性表——符号表

符号表
符号表最主要的目的是将一个键和一个值联系起来。如下图所示:
在这里插入图片描述
下边我们用链表的形式来创建符号表类。
插入方法

public void put(key key,value value){
        //符号表中已经存在键为key的键值对,找到并替换值为value即可
       Node n=head;
       while (n.next!=null){
           n=n.next;
           //判断n结点的键是否为key,如果是,则替换n结点的值
           if (n.key.equals(key)){
               n.value=value;
               return;
           }
       }
       //符号表中不存在键为key的键值对,只需创建新的结点,把新结点放在链表的头部即可
       Node newNode = new Node(key, value, null);
       Node oldfirst = head.next;
       newNode.next=oldfirst;
       head.next=newNode;
       //元素个数加一
       N++;
   }

删除方法

public void delete(key key){
        //找到键为key的键值对,把该结点从链表中删除
        Node n=head;
        while (n.next!=null) {
            //判断n结点的下一个结点是否为key,如果是,就删除
            if (n.next.key.equals(key)) {
                n.next = n.next.next;
                N--;
                return;
            }
            //变换n
            n = n.next;
        }
    }

查找方法

public value get(key key){
        Node n=head;
        while (n.next!=null){
            n=n.next;
            if (n.key.equals(key)){
                return n.value;
            }
        }
        return null;
    }

完整代码

public class SymbolTable<key,value> {
    private Node head;
    private int N;
    public class Node {
        public value value;
        public Node next;
        public key key;
        public Node(key key, value value, Node next) {
            this.key = key;
            this.value = value;
            this.next = next;
        }
    }
   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的键值对,找到并替换值为value即可
       Node n=head;
       while (n.next!=null){
           n=n.next;
           //判断n结点的键是否为key,如果是,则替换n结点的值
           if (n.key.equals(key)){
               n.value=value;
               return;
           }
       }
       //符号表中不存在键为key的键值对,只需创建新的结点,把新结点放在链表的头部即可
       Node newNode = new Node(key, value, null);
       Node oldfirst = head.next;
       newNode.next=oldfirst;
       head.next=newNode;
       //元素个数加一
       N++;
   }
   //删除键值对
    public void delete(key key){
        //找到键为key的键值对,把该结点从链表中删除
        Node n=head;
        while (n.next!=null) {
            //判断n结点的下一个结点是否为key,如果是,就删除
            if (n.next.key.equals(key)) {
                n.next = n.next.next;
                N--;
                return;
            }
            //变换n
            n = n.next;
        }
    }
    //从符号表中获取key对应的值
    public value get(key key){
        Node n=head;
        while (n.next!=null){
            n=n.next;
            if (n.key.equals(key)){
                return n.value;
            }
        }
        return null;
    }
}

上述符号表存在一个问题,即插入元素时总是插入到首位置,没有进行排序,下面对其进行改进
能进行排序的插入方法

public void put(key key,value value){
        //定义两个Node变量,记录当前结点和上一个节点
        Node cur=head.next;
        Node pre=head;
        while (cur!=null && key.compareTo(cur.key)>0){
            //变换当前结点和前一个结点即可
            pre=cur;
            cur=cur.next;
        }
        //如果键一样,则替换
        if (cur!=null && key.compareTo(cur.key)==0){
            cur.value=value;
            return;
        }
        //如果键不一样,把新结点插入到cur之前
        Node newNode = new Node(key, value, cur);
        pre.next=newNode;
        //元素个数+1
        N++;
    }

完整代码

public class OrderSymbolTable<key extends Comparable<key>,value> {
    private Node head;
    private int N;
    public class Node {
        public value value;
        public Node next;
        public key key;
        public Node(key key, value value, Node next) {
            this.key = key;
            this.value = value;
            this.next = next;
        }
    }
    public OrderSymbolTable(){
        this.head=new Node(null,null,null);
        this.N=0;
    }
    public int size(){
        return N;
    }
    //向符号表中删除键值对
    public void delete(key key){
        //找到键为key的键值对,把该结点从链表中删除
        Node n=head;
        while (n.next!=null) {
            //判断n结点的下一个结点是否为key,如果是,就删除
            if (n.next.key.equals(key)) {
                n.next = n.next.next;
                N--;
                return;
            }
            //变换n
            n = n.next;
        }
    }
    //插入键值对
    public void put(key key,value value){
        //定义两个Node变量,记录当前结点和上一个节点
        Node cur=head.next;
        Node pre=head;
        while (cur!=null && key.compareTo(cur.key)>0){
            //变换当前结点和前一个结点即可
            pre=cur;
            cur=cur.next;
        }
        //如果键一样,则替换
        if (cur!=null && key.compareTo(cur.key)==0){
            cur.value=value;
            return;
        }
        //如果键不一样,把新结点插入到cur之前
        Node newNode = new Node(key, value, cur);
        pre.next=newNode;
        //元素个数+1
        N++;
    }
    //从符号表中获取key对应的值
    public value get(key key){
        Node n=head;
        while (n.next!=null){
            n=n.next;
            if (n.key.equals(key)){
                return n.value;
            }
        }
        return null;
    }
}

b站详细讲解网址:http://yun.itheima.com/course/639.html

猜你喜欢

转载自blog.csdn.net/love521314123/article/details/107380597