1. 程式人生 > 其它 >資料結構:符號表

資料結構:符號表

技術標籤:資料結構與演算法符號表有序符號表鍵值對

1 符號表簡介

  1. 符號表最主要的目的是將一個鍵和一個值聯絡起來,其儲存的資料元素是由一個鍵和一個值共同組成的鍵值對資料;
  2. 我們可以根據鍵來查詢對應的值;
  3. 符號表中的鍵具有唯一性;

在這裡插入圖片描述
符號表的使用場景

應用查詢目的
字典找出單詞的釋義單詞釋義
圖書索引找出某個術語相關的頁碼術語一串頁碼
網路搜尋找出某個關鍵字對應的網頁關鍵字網頁名稱

2 符號表API設計

結點類

類名Node<Key, Value>
構造方法Node(Key key, Value value, Node next):建立Node物件
成員變數1.public Key key:儲存鍵
2.public Value value:儲存值
3.public Node next:儲存下一個結點

符號表

類名SymbolTable<Key, Value>
構造方法SymbolTable():建立SymbolTable物件
成員方法1.public Value get(Key key):根據鍵key,找對應的值
2.public void put(Key key,Value val):向符號表中插入一個鍵值對
3.public void delete(Key key):刪除鍵為key的鍵值對
4.public int size():獲取符號表的大小
成員變數1.private Node head:記錄首結點
2.private int N:記錄符號表中鍵值對的個數

3 符號表程式碼實現

public class SymbolTable<Key,Value> {
    //記錄首結點
    private Node head;
    //記錄符號表中元素的個數
    private int N;

    private class Node{
        //鍵
        public Key key;
        //值
        public Value value;
        //下一個結點
        public Node next;

        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 = n.next; //判斷n結點儲存的鍵是否為key,如果是,則替換n結點的值 if (n.key.equals(key)){ n.value = value; return; } } //如果符號表中不存在鍵為key的鍵值對,只需要建立新的結點,儲存要插入的鍵值對,把新結點插入到連結串列的頭部:head.next=新結點即可 Node newNode = new Node(key, value, null); Node oldFirst = head.next; newNode.next = oldFirst; head.next = newNode; //元素個數+1 N++; } //刪除符號表中鍵為key的鍵值對 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.next; } } //從符號表中獲取key對應的值 public Value get(Key key){ //找到鍵為key的結點 Node n = head; while(n.next!=null){ //變換n n = n.next; if (n.key.equals(key)){ return n.value; } } return null; } }
public class Test {
    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());
    }
}
3
老三
3
2

4 有序符號表

  1. 前面實現的符號表,我們稱之為無序符號表,因為在插入的時候,並沒有考慮鍵值對的順序;
  2. 然而在實際生活中,有時候我們需要根據鍵的大小進行排序,插入資料時要考慮順序,即有序符號表;
public class OrderSymbolTable<Key extends Comparable<Key>,Value> {
    //記錄首結點
    private Node head;
    //記錄符號表中元素的個數
    private int N;

    private class Node{
        //鍵
        public Key key;
        //值
        public Value value;
        //下一個結點
        public Node next;

        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 put(Key key,Value value){
        //定義兩個Node變數,分別記錄當前結點和當前結點的上一個結點
        Node curr = head.next;
        Node pre = head;
        while(curr!=null && key.compareTo(curr.key)>0){
            pre = curr;
            curr = curr.next;
        }
        //如果當前結點curr的鍵和要插入的key一樣,則替換
        if (curr!=null && key.compareTo(curr.key)==0){
            curr.value = value;
            return;
        }
        //如果curr的鍵和要插入的key不一樣,說明要插入的key小於curr的key,把新的結點插入到curr之前,且元素個數+1
        pre.next = new Node(key, value, curr);
        N++;
    }
    
    //刪除符號表中鍵為key的鍵值對
    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.next;
        }
    }

    //從符號表中獲取key對應的值
    public Value get(Key key){
        //找到鍵為key的結點
        Node n = head;
        while(n.next!=null){
            n = n.next;
            if (n.key.equals(key)){
                return n.value;
            }
        }
        return null;
    }
}