數據結構(四):符號表
一、 符號表概述
符號表是存儲鍵及對應值的數據結構,符號表中存儲的元素由鍵,值和指向下一個值的指針域組成,可通過鍵查找到對應的值。
符號表中,鍵必須是唯一的,而值可以不唯一。
日常生活中,根據關鍵字百度查找資料,根據目錄查找書籍內容,都是符號表使用的體現。
二、 符號表的構造
public class Node<Key, Value> {
// 符號表key public Key key;
// 符號表value public Value value;
// 指向下一個結點 public Node next;
public Node(Key key, Value value, Node next) { this.key = key; this.value = value; this.next = next; }
public static void main(String[] args) { Node node1 = new Node(1, "A", null); Node node2 = new Node(2, "B", null); Node node3 = new Node(3, "C", null); Node node4 = new Node(4, "D", null);
node1.next = node2; node2.next = node3; node3.next = node4; } } |
三、 無序符號表
public class SymbolTable<Key,Value> {
//聲明頭結點 public Node head;
//元素個數 public int N;
public SymbolTable() { head = new Node(null,null,null); N=0; }
/** * 符號表大小 * @return */ public int size() { return N; }
/** * 符號表是否為空 * @return */ public boolean isEmpty() { return N==0; }
/** * 根據key獲取value * @param key * @return */ public Value get(Key key) { Node node = head; while(node.next!=null) { node = node.next; if(node.key.equals(key)) { return (Value) node.value; } } return null; }
/** * 根據key刪除value * @param key */ public void del(Key key) { Node node = head; while(node.next!=null) { if(node.next.key.equals(key)) { node.next = node.next.next; N--; return; } node = node.next; } }
/** * 存儲鍵值對 * @param key * @param value */ public void put(Key key,Value value) { //符號表中已經存在相同key的情況,替換value值 Node node = head; while(node.next!=null) { node = node.next; if(node.key.equals(key)) { node.value = value; return; } }
//符號表中不存在相同key的情況,新增value值 Node firstNode = head.next; Node newFirstNode = new Node(key, value, firstNode); head.next = newFirstNode;
N++; } } |
四、 有序符號表
上述的符號表,插入元素時沒有根據key進行排序,是無序的。
日常使用中,會出現需要根據key進行排序的需求,實現思路是在put方法時,去遍歷比較key和當前結點的key大小,當key比當前結點key大時則繼續往下走,走到發現沒有比key大的當前結點時
比較兩個key是否相等,是則替換value,不是則新增結點,並實現連接。
public class OrderSymbolTable<Key extends Comparable<Key>,Value>{
//聲明頭結點 public Node head;
//元素個數 public int N;
public OrderSymbolTable() { head = new Node(null,null,null); N=0; }
/** * 符號表大小 * @return */ public int size() { return N; }
/** * 符號表是否為空 * @return */ public boolean isEmpty() { return N==0; }
/** * 根據key獲取value * @param key * @return */ public Value get(Key key) { Node node = head; while(node.next!=null) { node = node.next; if(node.key.equals(key)) { return (Value) node.value; } } return null; }
/** * 根據key刪除value * @param key */ public void del(Key key) { Node node = head; while(node.next!=null) { if(node.next.key.equals(key)) { node.next = node.next.next; N--; return; } node = node.next; } }
/** * 存儲鍵值對 * @param key * @param value */ public void put(Key key,Value value) { Node curr = head.next; Node pre = head;
//發現比符號表中存儲的key大,則繼續遍歷 while(curr != null && key.compareTo((Key) curr.key)>0) { pre = curr; curr = curr.next; }
//上述遍歷完成后會出現兩種情況 //1、出現key相等的情況 if(curr != null && key.equals((Key) curr.key)) { curr.value = value; return; }
//2、沒有key相等的情況 Node newNode = new Node<Key, Value>(key, value, curr); pre.next = newNode;
N++; } } |