符号表--01---概述与实现

发布时间:2026/8/25 7:44:56

符号表--01---概述与实现
符号表定义:符号表最主要的目的就是将一个键和一个值联系起来符号表能够将存储的数据元素是一个键和一个值共同组成的键值对数据我们可以根据键来查找对应的值。符号表中键具有唯一性。使用场景:符号表在实际生活中的使用场景是非常广泛的见下表链表实现符号表API设计:结点类符号表代码实现:publicclassSymbolTableKey,Value{//记录首结点privateNodehead;//记录符号表中元素的个数privateintN;publicSymbolTable(){this.headnewNode(null,null,null);this.N0;}//获取符号表中键值对的个数publicintsize(){returnN;}//往符号表中插入键值对publicvoidput(Keykey,Valuevalue){//符号表中已经存在了键为key的键值对那么只需要找到该结点替换值为value即可Nodenhead;while(n.next!null){//变换nnn.next;//判断n结点存储的键是否为key如果是则替换n结点的值if(n.key.equals(key)){n.valuevalue;return;}}//如果符号表中不存在键为key的键值对只需要创建新的结点保存要插入的键值对把新结点插入到链表的头部 head.next新结点即可NodenewNodenewNode(key,value,null);NodeoldFirsthead.next;newNode.nextoldFirst;head.nextnewNode;//元素个数1N;}//删除符号表中键为key的键值对publicvoiddelete(Keykey){//找到键为key的结点把该结点从链表中删除Nodenhead;while(n.next!null){//判断n结点的下一个结点的键是否为key如果是就删除该结点if(n.next.key.equals(key)){n.nextn.next.next;N--;return;}//变换nnn.next;}}//从符号表中获取key对应的值publicValueget(Keykey){//找到键为key的结点Nodenhead;while(n.next!null){//变换nnn.next;if(n.key.equals(key)){returnn.value;}}returnnull;}//节点类privateclassNode{//键publicKeykey;//值publicValuevalue;//下一个结点publicNodenext;publicNode(Keykey,Valuevalue,Nodenext){this.keykey;this.valuevalue;this.nextnext;}}}测试:publicclassSymbolTableTest{publicstaticvoidmain(String[]args){//创建符号表对象SymbolTableInteger,StringsymbolTablenewSymbolTable();//测试put方法插入,替换symbolTable.put(1,乔峰);symbolTable.put(2,虚竹);symbolTable.put(3,段誉);System.out.println(插入完毕后元素的个数为:symbolTable.size());symbolTable.put(2,慕容复);System.out.println(替换完毕后的元素的个数为:symbolTable.size());//测试get方法System.out.println(替换完毕后键2对应的值为:symbolTable.get(2));//测试删除方法symbolTable.delete(2);System.out.println(删除完毕后元素的个数:symbolTable.size());}}有序符号表刚才实现的符号表我们可以称之为无序符号表因为在插入的时候并没有考虑键值对的顺序而在实际生活中有时候我们需要根据键的大小进行排序插入数据时要考虑顺序那么接下来我们就实现一下有序符号表。有序链表实现:publicclassOrderSymbolTableKeyextendsComparableKey,Value{//记录首结点privateNodehead;//记录符号表中元素的个数privateintN;privateclassNode{//键publicKeykey;//值publicValuevalue;//下一个结点publicNodenext;publicNode(Keykey,Valuevalue,Nodenext){this.keykey;this.valuevalue;this.nextnext;}}publicOrderSymbolTable(){this.headnewNode(null,null,null);this.N0;}//获取符号表中键值对的个数publicintsize(){returnN;}//往符号表中插入键值对publicvoidput(Keykey,Valuevalue){//定义两个Node变量分别记录当前结点和当前结点的上一个结点Nodecurrhead.next;Nodeprehead;while(curr!nullkey.compareTo(curr.key)0){//变换当前结点和前一个结点即可precurr;currcurr.next;}//如果当前结点curr的键和要插入的key一样则替换if(curr!nullkey.compareTo(curr.key)0){curr.valuevalue;return;}//如果当前结点curr的键和要插入的key不一样把新的结点插入到curr之前NodenewNodenewNode(key,value,curr);pre.nextnewNode;//元素的个数1N;}//删除符号表中键为key的键值对publicvoiddelete(Keykey){//找到键为key的结点把该结点从链表中删除Nodenhead;while(n.next!null){//判断n结点的下一个结点的键是否为key如果是就删除该结点if(n.next.key.equals(key)){n.nextn.next.next;N--;return;}//变换nnn.next;}}//从符号表中获取key对应的值publicValueget(Keykey){//找到键为key的结点Nodenhead;while(n.next!null){//变换nnn.next;if(n.key.equals(key)){returnn.value;}}returnnull;}}debug测试:数组二分查找实现:使用一对平行数组一个存储键一个存储值。二分查找的思想是在内部维护一个按照key排好序的二维数组每一次查找的时候跟中间元素进行比较如果该元素小则继续左半部分递归查找否则继续右半部分递归查找。整个实现代码如下二分查找的 rank() 方法至关重要当键在表中时它能够知道该键的位置当键不在表中时它也能知道在何处插入新键。/** * 有序数组符号表 */publicclassSymbolTableKextendsComparableK,V{privateK[]keys;//键数组privateV[]values;//值数组publicintsize;privatestaticfinalintinitSize10;//默认数组初始大小publicSymbolTable(){this(initSize);}publicSymbolTable(intcapacity){keys(K[])newComparable[capacity];values(V[])newObject[capacity];}/** * 查找键为K的值 */publicVget(Kk){if(isEmpty()){returnnull;}//在数组中找出值intirank(k);if(isizekeys[i].compareTo(k)0){returnvalues[i];}returnnull;}/** * 插入要给键值对 */publicvoidput(Kk,Vv){intirank(k);//如果已经存在了键就交换值if(isizekeys[i].compareTo(k)0){values[i]v;return;}//否则就把键值插入到最小于K的值之后for(intjsize;ji;j--){keys[j]keys[j-1];values[j]values[j-1];}keys[i]k;values[i]v;size;}publicbooleanisEmpty(){returnsize0;}publicintrank(Kk){intlow0;//低位起始下标inthighsize-1;//高位下标长度-1//高低交叉之前都一直查询while(lowhigh){intmidlow(high-low)/2;//找到中位下标intcmdk.compareTo(keys[mid]);//获取数组中中位值与比较K的大小//如果两个值相等说明找到了if(cmd0){returnmid;//小于0说明比中位值小从数组中中位置左侧搜索}elseif(cmd0){highmid-1;//和上面相反从数组右侧搜索}else{lowmid1;}}//否侧返回低位的值这个值就是小于被查找值的数量returnlow;}}debug测试:总结:本文介绍了符号表这一抽象数据结构然后介绍了两种基本实现基于无序链表的实现和基于有序数组的实现两种实现的时间复杂度如下无序链表实现:插入的时候先要查找如果存在则更新value查找的时候需要从链表头进行查找所以插入和查找的平均时间复杂度均为O(n)数组二分查找:采用二分查找只需要最多 logN1次的比较即可找到对应元素所以查找效率比较高。但是对于插入元素来说每一次插入不存在的元素需要将该元素放到指定的位置然后将他后面的元素依次后移所以平均时间复杂度O(n)对于插入来说效率仍然比较低。使用有序数组的二分查找法提高了符号表的查找速度但是插入效率仍旧没有得到提高而且在要维护数组有序还需要进行排序操作。这两种实现方式简单直观但是无法同时达到较高查找和插入效率。本文只是一个引子后面的系列文章将会介绍二叉查找树平衡查找树以及哈希表。数组实现和链表实现对比:

相关新闻

I2C协议进阶:快速模式、高速模式与10位寻址详解

I2C协议进阶:快速模式、高速模式与10位寻址详解

2026/8/25 7:44:56

1. 从标准模式到性能跃迁:为什么需要更快的I2C?搞嵌入式开发的朋友,对I2C(Inter-Integrated Circuit)协议肯定不陌生。它那两根线(SDA数据线、SCL时钟线)的简洁设计,让连接多个低速外…

Mendeley文献管理实战:从高效导入到精准引用,打造个人学术知识库

Mendeley文献管理实战:从高效导入到精准引用,打造个人学术知识库

2026/8/25 7:44:56

1. 从文献混乱到高效管理:为什么我坚持用Mendeley如果你和我一样,每天需要和几十甚至上百篇PDF文献打交道,那你一定经历过这种痛苦:电脑桌面或下载文件夹里堆满了以“paper1_final_revised.pdf”这种毫无意义命名的文件&#xff1…

Mendeley文献管理工具:从入门到精通,打造高效学术工作流

Mendeley文献管理工具:从入门到精通,打造高效学术工作流

2026/8/25 7:44:56

1. 从文献混乱到高效管理:为什么你需要Mendeley如果你正在读研、搞科研,或者从事任何需要大量阅读和引用文献的工作,那么你肯定对下面这个场景不陌生:电脑里塞满了从各个数据库下载的PDF文件,文件名千奇百怪&#xff0…

监听每一次开关访问:feature-flags的4个事件如何助力你的审计与监控

监听每一次开关访问:feature-flags的4个事件如何助力你的审计与监控

2026/8/25 8:24:57

监听每一次开关访问:feature-flags的4个事件如何助力你的审计与监控 【免费下载链接】feature-flags A Laravel package for handling feature flags 项目地址: https://gitcode.com/gh_mirrors/fe/feature-flags 如果你在用 Laravel 管理功能开关&#xff0…

别再翻车了:SenseNova-U1.5-8B-MoT常见坑全解析——密集文字、手部畸形与编辑漂移怎么破

别再翻车了:SenseNova-U1.5-8B-MoT常见坑全解析——密集文字、手部畸形与编辑漂移怎么破

2026/8/25 8:24:57

别再翻车了:SenseNova-U1.5-8B-MoT常见坑全解析——密集文字、手部畸形与编辑漂移怎么破 【免费下载链接】SenseNova-U1.5-8B-MoT 项目地址: https://ai.gitcode.com/SenseNova/SenseNova-U1.5-8B-MoT SenseNova-U1.5-8B-MoT 是商汤基于 NEO-unify 架构推出…

VSCode配置Eigen头文件库的完整指南

VSCode配置Eigen头文件库的完整指南

2026/8/25 8:24:57

1. 为什么Eigen不是“装上就能用”的库——从C编译本质讲清配置逻辑 很多人在Windows上用VSCode配Eigen时&#xff0c;第一反应是“不就是下载个头文件扔进项目里吗”&#xff0c;结果一写 #include <Eigen/Dense> 就报错&#xff1a; fatal error: Eigen/Dense: No …

深入 pgwatch 源码:Reaper 采集架构与 400 个数据源故障不停机的韧性设计

深入 pgwatch 源码:Reaper 采集架构与 400 个数据源故障不停机的韧性设计

2026/8/25 8:24:57

深入 pgwatch 源码&#xff1a;Reaper 采集架构与 400 个数据源故障不停机的韧性设计 【免费下载链接】pgwatch &#x1f52c;pgwatch: PostgreSQL metrics monitor/dashboard 项目地址: https://gitcode.com/gh_mirrors/pg/pgwatch pgwatch 是一款开源的 PostgreSQL 监…

pytest-allure定制化测试报告:从技术日志到业务说明书

pytest-allure定制化测试报告:从技术日志到业务说明书

2026/8/25 8:24:57

1. 项目概述&#xff1a;为什么一份“好看又管用”的测试报告比跑通用例更重要 我带过三支不同规模的测试团队&#xff0c;从五人初创小队到百人级质量中台&#xff0c;有个现象特别扎眼&#xff1a;90%的自动化脚本能稳定运行&#xff0c;但80%的测试报告没人点开看第二遍。不…

Canvas图形引擎实战:数据驱动路口渠化图绘制与性能优化

Canvas图形引擎实战:数据驱动路口渠化图绘制与性能优化

2026/8/25 8:14:57

1. 项目概述&#xff1a;从需求到实现的思路拆解最近在做一个交通仿真相关的项目&#xff0c;里面有个核心需求是要动态生成各种复杂的路口渠化图。所谓路口渠化&#xff0c;简单说就是通过画线、设置导流岛、划分车道这些手段&#xff0c;来引导车流、提高路口通行效率和安全性…

[光学原理与应用-521]:对光的错误理解与纠偏

[光学原理与应用-521]:对光的错误理解与纠偏

2026/8/24 19:53:32

首先光是一种能量的载体和形态&#xff0c;宏观上观察到的光是由无数个微观的光量子组成的&#xff0c;每个光子在产生的瞬间&#xff0c;其在真空的空间中以确定不变的速度沿着一个初始的方向一直向前&#xff0c;在微观层面&#xff0c;每个光量子的运动轨迹是以波函数所展现…

SIP通话转接原理与REFER方法实战解析

SIP通话转接原理与REFER方法实战解析

2026/8/24 19:56:07

1. 通话转接不是“挂断再拨号”&#xff0c;而是SIP会话的动态重定向你有没有遇到过这样的场景&#xff1a;客服坐席A正在和客户通电话&#xff0c;突然需要把这通对话无缝转给专家坐席B&#xff0c;客户完全感知不到中间的断连——既没听到忙音&#xff0c;也没被要求重新拨号…

Kolla-ansible单节点OpenStack部署实战:从环境准备到排坑指南

Kolla-ansible单节点OpenStack部署实战:从环境准备到排坑指南

2026/8/24 21:16:09

1. 为什么选择Kolla-ansible来部署单节点OpenStack&#xff1f;如果你正在寻找一种能把OpenStack从“概念”快速变成“可用的实验环境”的方法&#xff0c;那么Kolla-ansible几乎是当前最主流、最省心的选择。我见过太多人卡在手动编译依赖、配置服务、处理版本冲突的泥潭里&am…

三步把QQ空间历史说说导出到本地:GetQzonehistory 极简指南

三步把QQ空间历史说说导出到本地:GetQzonehistory 极简指南

2026/8/25 0:04:34

三步把QQ空间历史说说导出到本地&#xff1a;GetQzonehistory 极简指南 【免费下载链接】GetQzonehistory 获取QQ空间发布的历史说说 项目地址: https://gitcode.com/GitHub_Trending/ge/GetQzonehistory Meta Description&#xff1a;GetQzonehistory 是一个QQ空间历史说…

洛谷 P7912:[CSP-J 2021 T4] 小熊的果篮 ← 双向链表

洛谷 P7912:[CSP-J 2021 T4] 小熊的果篮 ← 双向链表

2026/8/25 0:04:35

【题目来源】 https://www.luogu.com.cn/problem/P7912 【题目描述】 小熊的水果店里摆放着一排 n 个水果。每个水果只可能是苹果或桔子&#xff0c;从左到右依次用正整数 1,2,…,n 编号。连续排在一起的同一种水果称为一个“块”。小熊要把这一排水果挑到若干个果篮里&#x…

Transformers.js 网页端图像抠图实战:零后端 3 行代码返回透明 PNG

Transformers.js 网页端图像抠图实战:零后端 3 行代码返回透明 PNG

2026/8/25 0:04:35

Transformers.js 网页端图像抠图实战&#xff1a;零后端 3 行代码返回透明 PNG 【免费下载链接】transformers.js State-of-the-art Machine Learning for the web. Run &#x1f917; Transformers directly in your browser, with no need for a server! 项目地址: https:/…

摆脱论文困扰!盘点2026年全网爆红的的AI论文写作工具

摆脱论文困扰!盘点2026年全网爆红的的AI论文写作工具

2026/8/22 2:02:26

一天写完毕业论文在2026年已不再是天方夜谭。2026年最炸裂、实测能大幅提速的AI论文写作工具&#xff0c;覆盖选题构思、文献整理、内容生成、格式排版等核心场景&#xff0c;真正帮你高效搞定论文难题。 一、全流程王者&#xff1a;一站式搞定论文全链路&#xff08;一天定稿首…

导师推荐!2026最新AI论文工具测评与实用推荐

导师推荐!2026最新AI论文工具测评与实用推荐

2026/8/22 4:13:47

2026年真正好用的AI论文工具&#xff0c;核心看生成的论文质量、低AI味、格式正确、学术适配四大指标。综合实测&#xff0c;千笔AI、ThouPen、豆包、DeepSeek、Grammarly 是当前最值得推荐的梯队&#xff0c;覆盖从免费到付费、从中文到英文、从文科到理工的全场景需求。 一、…

告别游戏崩溃:XCOM 2模组管理器的智能革命

告别游戏崩溃:XCOM 2模组管理器的智能革命

2026/8/22 1:32:34

告别游戏崩溃&#xff1a;XCOM 2模组管理器的智能革命 【免费下载链接】xcom2-launcher The Alternative Mod Launcher (AML) is a replacement for the default game launchers from XCOM 2 and XCOM Chimera Squad. 项目地址: https://gitcode.com/gh_mirrors/xc/xcom2-lau…