数据结构与算法之符号表

简介: 数据结构与算法之符号表

符号表简介


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


bec0b16b1df0472fbddc2bd06047e309.png


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


符号表在实际生活中的使用场景是非常广泛的,见下表:


image.png


符号表API设计


结点类:


image.png

符号表:


image.png

符号表实现


// 符号表
public class SymbolTable<Key,Value> {
  //记录首结点
  private Node head;
  //记录符号表中元素的个数
  private int N;
  public SymbolTable() {
    head = new Node(null,null,null);
    N=0;
  }
  //获取符号表中键值对的个数
  public int size(){
    return N;
  }
  //往符号表中插入键值对
  public void put(Key key,Value value){
    //先从符号表中查找键为key的键值对
    Node n = head;
    while(n.next!=null){
      n = n.next;
      if (n.key.equals(key)){
        n.value=value;
        return;
      }
    }
    //符号表中没有键为key的键值对
    Node oldFirst = head.next;
    Node newFirst = new Node(key,value,oldFirst);
    head.next = newFirst;
    //个数+1
    N++;
  }
  //删除符号表中键为key的键值对
  public void delete(Key key){
    Node n = head;
    while(n.next!=null){
      if (n.next.key.equals(key)){
        n.next = n.next.next;
        N--;
        return;
      }
    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;
  }
  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 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());
  }
}


有序符号表


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

//有序符号表
public class OrderSymbolTable<Key extends Comparable<Key>,Value> {
  //记录首结点
  private Node head;
  //记录符号表中元素的个数
  private int N;
  public OrderSymbolTable() {
    head = new Node(null,null,null);
    N=0;
  }
  //获取符号表中键值对的个数
  public int size(){
    return N;
  }
  //往符号表中插入键值对
  public void put(Key key,Value value){
    //记录当前结点
    Node curr = head.next;
    //记录上一个结点
    Node pre = head;
    //1.如果key大于当前结点的key,则一直寻找下一个结点
    while(curr!=null && key.compareTo(curr.key)>0){
      pre = curr;
      curr = curr.next;
    }
    //2.如果当前结点curr的key和将要插入的key一样,则替换
    if (curr!=null && curr.key.compareTo(key)==0){
      curr.value=value;
      return;
    }
    //3.没有找到相同的key,把新结点插入到curr之前
    Node newNode = new Node(key, value, curr);
    pre.next = newNode;
  }
  //删除符号表中键为key的键值对
  public void delete(Key key){
    Node n = head;
    while(n.next!=null){
      if (n.next.key.equals(key)){
        n.next = n.next.next;
        N--;
        return;
      }
    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;
  }
  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 class Test {
  public static void main(String[] args) throws Exception {
    OrderSymbolTable<Integer, String> bt = new OrderSymbolTable<>();
    bt.put(4, "二哈");
    bt.put(3, "张三");
    bt.put(1, "李四");
    bt.put(1, "aa");
    bt.put(5, "王五");
  }
}


目录
相关文章
|
存储 API
数据结构——符号表
数据结构——符号表
数据结构——符号表
|
算法 C# 网络协议
浅谈算法和数据结构: 六 符号表及其基本实现
原文:浅谈算法和数据结构: 六 符号表及其基本实现 前面几篇文章介绍了基本的排序算法,排序通常是查找的前奏操作。从本文开始介绍基本的查找算法。 在介绍查找算法,首先需要了解符号表这一抽象数据结构,本文首先介绍了什么是符号表,以及这一抽象数据结构的的API,然后介绍了两种简单的符号表的实现方式。
1073 0
|
3月前
|
C语言
【数据结构】栈和队列(c语言实现)(附源码)
本文介绍了栈和队列两种数据结构。栈是一种只能在一端进行插入和删除操作的线性表,遵循“先进后出”原则;队列则在一端插入、另一端删除,遵循“先进先出”原则。文章详细讲解了栈和队列的结构定义、方法声明及实现,并提供了完整的代码示例。栈和队列在实际应用中非常广泛,如二叉树的层序遍历和快速排序的非递归实现等。
307 9
|
3月前
|
存储 算法
非递归实现后序遍历时,如何避免栈溢出?
后序遍历的递归实现和非递归实现各有优缺点,在实际应用中需要根据具体的问题需求、二叉树的特点以及性能和空间的限制等因素来选择合适的实现方式。
48 1
|
23天前
|
存储 C语言 C++
【C++数据结构——栈与队列】顺序栈的基本运算(头歌实践教学平台习题)【合集】
本关任务:编写一个程序实现顺序栈的基本运算。开始你的任务吧,祝你成功!​ 相关知识 初始化栈 销毁栈 判断栈是否为空 进栈 出栈 取栈顶元素 1.初始化栈 概念:初始化栈是为栈的使用做准备,包括分配内存空间(如果是动态分配)和设置栈的初始状态。栈有顺序栈和链式栈两种常见形式。对于顺序栈,通常需要定义一个数组来存储栈元素,并设置一个变量来记录栈顶位置;对于链式栈,需要定义节点结构,包含数据域和指针域,同时初始化栈顶指针。 示例(顺序栈): 以下是一个简单的顺序栈初始化示例,假设用C语言实现,栈中存储
134 77
|
23天前
|
存储 C++ 索引
【C++数据结构——栈与队列】环形队列的基本运算(头歌实践教学平台习题)【合集】
【数据结构——栈与队列】环形队列的基本运算(头歌实践教学平台习题)【合集】初始化队列、销毁队列、判断队列是否为空、进队列、出队列等。本关任务:编写一个程序实现环形队列的基本运算。(6)出队列序列:yzopq2*(5)依次进队列元素:opq2*(6)出队列序列:bcdef。(2)依次进队列元素:abc。(5)依次进队列元素:def。(2)依次进队列元素:xyz。开始你的任务吧,祝你成功!(4)出队一个元素a。(4)出队一个元素x。
40 13
【C++数据结构——栈与队列】环形队列的基本运算(头歌实践教学平台习题)【合集】
|
23天前
|
存储 C语言 C++
【C++数据结构——栈与队列】链栈的基本运算(头歌实践教学平台习题)【合集】
本关任务:编写一个程序实现链栈的基本运算。开始你的任务吧,祝你成功!​ 相关知识 初始化栈 销毁栈 判断栈是否为空 进栈 出栈 取栈顶元素 初始化栈 概念:初始化栈是为栈的使用做准备,包括分配内存空间(如果是动态分配)和设置栈的初始状态。栈有顺序栈和链式栈两种常见形式。对于顺序栈,通常需要定义一个数组来存储栈元素,并设置一个变量来记录栈顶位置;对于链式栈,需要定义节点结构,包含数据域和指针域,同时初始化栈顶指针。 示例(顺序栈): 以下是一个简单的顺序栈初始化示例,假设用C语言实现,栈中存储整数,最大
41 9
|
23天前
|
C++
【C++数据结构——栈和队列】括号配对(头歌实践教学平台习题)【合集】
【数据结构——栈和队列】括号配对(头歌实践教学平台习题)【合集】(1)遇到左括号:进栈Push()(2)遇到右括号:若栈顶元素为左括号,则出栈Pop();否则返回false。(3)当遍历表达式结束,且栈为空时,则返回true,否则返回false。本关任务:编写一个程序利用栈判断左、右圆括号是否配对。为了完成本关任务,你需要掌握:栈对括号的处理。(1)遇到左括号:进栈Push()开始你的任务吧,祝你成功!测试输入:(()))
34 7
|
3月前
|
存储 缓存 算法
在C语言中,数据结构是构建高效程序的基石。本文探讨了数组、链表、栈、队列、树和图等常见数据结构的特点、应用及实现方式
在C语言中,数据结构是构建高效程序的基石。本文探讨了数组、链表、栈、队列、树和图等常见数据结构的特点、应用及实现方式,强调了合理选择数据结构的重要性,并通过案例分析展示了其在实际项目中的应用,旨在帮助读者提升编程能力。
92 5
|
3月前
|
存储 算法 Java
数据结构的栈
栈作为一种简单而高效的数据结构,在计算机科学和软件开发中有着广泛的应用。通过合理地使用栈,可以有效地解决许多与数据存储和操作相关的问题。
108 21