符号表最主要的目的就是将一个键和一个值联系起来,符号表能够将存储的数据元素是一个键和一个值共同组成的 键值对数据,我们可以根据键来查找对应的值。

符号表中,键具有唯一性。
image.png

代码实现:

  1. package 符号表;
  2. public class SymbolTable<Key, Value> {
  3. //记录首结点
  4. private Node head;
  5. //记录符号表中元素的个数
  6. private int N;
  7. public SymbolTable() {
  8. head = new Node(null, null, null);
  9. N = 0;
  10. }
  11. //获取符号表中键值对的个数
  12. public int size() {
  13. return N;
  14. }
  15. //往符号表中插入键值对
  16. public void put(Key key, Value value) {
  17. //先从符号表中查找键为key的键值对
  18. Node n = head;
  19. while (n.next != null) {
  20. n = n.next;
  21. if (n.key.equals(key)) {
  22. n.value = value;
  23. return;
  24. }
  25. }
  26. //符号表中没有键为key的键值对
  27. Node oldFirst = head.next;
  28. Node newFirst = new Node(key, value, oldFirst);
  29. head.next = newFirst;
  30. //个数+1
  31. N++;
  32. }
  33. //删除符号表中键为key的键值对
  34. public void delete(Key key) {
  35. Node n = head;
  36. while (n.next != null) {
  37. if (n.next.key.equals(key)) {
  38. n.next = n.next.next;
  39. N--;
  40. return;
  41. }
  42. n = n.next;
  43. }
  44. }
  45. //从符号表中获取key对应的值
  46. public Value get(Key key) {
  47. Node n = head;
  48. while (n.next != null) {
  49. n = n.next;
  50. if (n.key.equals(key)) {
  51. return n.value;
  52. }
  53. }
  54. return null;
  55. }
  56. private class Node {
  57. //键
  58. public Key key;
  59. //值
  60. public Value value;
  61. //下一个结点
  62. public Node next;
  63. public Node(Key key, Value value, Node next) {
  64. this.key = key;
  65. this.value = value;
  66. this.next = next;
  67. }
  68. }
  69. }

有序符号表

刚才实现的符号表,我们可以称之为无序符号表,因为在插入的时候,并没有考虑键值对的顺序,而在实际生活 中,有时候我们需要根据键的大小进行排序,插入数据时要考虑顺序,那么接下来我们就实现一下有序符号表。

代码实现:

  1. package 符号表;
  2. public class OrderSymbolTable<Key extends Comparable, Value> {
  3. //记录首结点
  4. private Node head;
  5. //记录符号表中元素的个数
  6. private int N;
  7. public OrderSymbolTable() {
  8. head = new Node(null, null, null);
  9. N = 0;
  10. }
  11. //获取符号表中键值对的个数
  12. public int size() {
  13. return N;
  14. }
  15. //往符号表中插入键值对
  16. public void put(Key key, Value value) {
  17. //记录当前结点
  18. Node curr = head.next;
  19. //记录上一个结点
  20. Node pre = head;
  21. //1.如果key大于当前结点的key,则一直寻找下一个结点
  22. while (curr != null && key.compareTo(curr.key) > 0) {
  23. pre = curr;
  24. curr = curr.next;
  25. }
  26. //2.如果当前结点curr的key和将要插入的key一样,则替换
  27. if (curr != null && curr.key.compareTo(key) == 0) {
  28. curr.value = value;
  29. return;
  30. }
  31. //3.没有找到相同的key,把新结点插入到curr之前
  32. Node newNode = new Node(key, value, curr);
  33. pre.next = newNode;
  34. }
  35. //删除符号表中键为key的键值对
  36. public void delete(Key key) {
  37. Node n = head;
  38. while (n.next != null) {
  39. if (n.next.key.equals(key)) {
  40. n.next = n.next.next;
  41. N--;
  42. return;
  43. }
  44. n = n.next;
  45. }
  46. }
  47. //从符号表中获取key对应的值
  48. public Value get(Key key) {
  49. Node n = head;
  50. while (n.next != null) {
  51. n = n.next;
  52. if (n.key.equals(key)) {
  53. return n.value;
  54. }
  55. }
  56. return null;
  57. }
  58. private class Node {
  59. //键
  60. public Key key;
  61. //值
  62. public Value value;
  63. //下一个结点
  64. public Node next;
  65. public Node(Key key, Value value, Node next) {
  66. this.key = key;
  67. this.value = value;
  68. this.next = next;
  69. }
  70. }
  71. }