1. 程式人生 > 實用技巧 >2013_符號表

2013_符號表

3. 符號表

符號表最主要的目的就是將一個鍵和一個值聯絡起來, 符號表能夠將儲存的資料元素是一個鍵和一個值共同組成的鍵值對資料, 我們可以根據鍵來查詢對應的值.

符號表中 具有唯一性. 如

  1. 字典: 鍵: 單詞 ; 值: 釋義
  2. 圖書索引: 鍵: 術語; 值: 頁碼
  3. 網路搜尋: 鍵: 關鍵字; 值: 網面名稱

3.1 無序符號表

3.1.1 API設計

3.1.1.1 節點類

類名 Node<Key,Value>
構造器 Node(Key key, Value value, Node next)
成員變數 1. public Key key; 儲存鍵
2. public Value value; 儲存值
3. public Node next; 下一個結點

3.1.1.2 符號表

類名 SymbolTable<Key, Value>
構造方法 SymbolTable()
成員方法 1. public Value get(Key key);
2. public void put(Key key, Value value);
3. public void delete(Key key);
4. public int size();
成員變數 1. private Node head;
2. private int N;

3.1.2 實現

package c_symbol;

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是否為key, 如果是, 替換值
            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;

        //元素個數+1
        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) {
        //找到鍵為key的結點
        Node n = head;

        while(n.next != null) {
            //變換n
            n = n.next;
            if(n.key.equals(key)) {
                return n.value;
            }
        }
        return null;
    }
}

3.1.3 測試

package c_symbol;

/**
 * 符號表測試
 */
public class SymbolTableTest {
    public static void main(String[] args) {
        //建立物件
        SymbolTable<Integer, String> symbolTable = new SymbolTable<>();
        //put
        symbolTable.put(1, "tom");
        symbolTable.put(2, "jerry");
        symbolTable.put(3, "emy");
        System.out.println("插入完成後元素個數" + symbolTable.size());

        symbolTable.put(2, "bob");
        System.out.println("替換完成元素個數" + symbolTable.size());
        System.out.println("-----------");

        //get
        System.out.println("替換完成後, 鍵2對應的值" + symbolTable.get(2));


        //delete
        symbolTable.delete(2);
        System.out.println("刪除後元素個數" + symbolTable.size());

    }
}

插入完成後元素個數3
替換完成元素個數3
-----------
替換完成後, 鍵2對應的值bob
刪除後元素個數2

3.2 有序符號表

前面實現的符號表, 沒有考慮鍵值對的順序, 實際需求中我們需要考慮順序, 根據鍵的大小進行排序, 插入資料時需要考慮順序.

3.2.1 實現

   //插入(有序插入)
    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;
        }
        //如噹噹前結點的鍵和key不一樣, 插入到curr之前
        Node newNode = new Node(key, value, curr);
        pre.next = newNode;
        //元素個數+1;
        N++;
    }

3.2.2 測試

package c_symbol;

/**
 * 有序符號表測試
 */
public class OrderSymbolTableTest {
    public static void main(String[] args) {
        //建立物件
        OrderSymbolTable<Integer, String> table = new OrderSymbolTable<>();
        table.put(1, "張三");
        table.put(2, "李四");
        table.put(4, "趙六");
        table.put(7, "田七");


        table.put(3, "王五");
    }
}

張三
李四
王五
趙六
田七