查找表结构

article/2025/9/16 22:26:48

查找表介绍

在日常生活中,几乎每天都要进行一些查找的工作,在电话簿中查阅某个人的电话号码;在电脑的文件夹中查找某个具体的文件等等。本节主要介绍用于查找操作的数据结构——查找表。

查找表是由同一类型的数据元素构成的集合。例如电话号码簿和字典都可以看作是一张查找表。

一般对于查找表有以下几种操作:

  • 在查找表中查找某个具体的数据元素;
  • 在查找表中插入数据元素;
  • 从查找表中删除数据元素;

静态查找表和动态查找表

在查找表中只做查找操作,而不改动表中数据元素,称此类查找表为静态查找表;反之,在查找表中做查找操作的同时进行插入数据或者删除数据的操作,称此类表为动态查找表。

关键字

在查找表查找某个特定元素时,前提是需要知道这个元素的一些属性。例如,每个人上学的时候都会有自己唯一的学号,因为你的姓名、年龄都有可能和其他人是重复的,唯独学号不会重复。而学生具有的这些属性(学号、姓名、年龄等)都可以称为关键字。

关键字又细分为主关键字和次关键字。若某个关键字可以唯一地识别一个数据元素时,称这个关键字为主关键字,例如学生的学号就具有唯一性;反之,像学生姓名、年龄这类的关键字,由于不具有唯一性,称为次关键字。

如何进行查找?

不同的查找表,其使用的查找方法是不同的。例如每个人都有属于自己的朋友圈,都有自己的电话簿,电话簿中数据的排序方式是多种多样的,有的是按照姓名的首字母进行排序,这种情况在查找时,就可以根据被查找元素的首字母进行顺序查找;有的是按照类别(亲朋好友)进行排序。在查找时,就需要根据被查找元素本身的类别关键字进行排序。

具体的查找方法需要根据实际应用中具体情况而定。


顺序查找算法(C++)

静态查找表既可以使用顺序表表示,也可以使用链表结构表示。虽然一个是数组、一个链表,但两者在做查找操作时,基本上大同小异。

顺序查找的实现

静态查找表用顺序存储结构表示时,顺序查找的查找过程为:从表中的最后一个数据元素开始,逐个同记录的关键字做比较,如果匹配成功,则查找成功;反之,如果直到表中第一个关键字查找完也没有成功匹配,则查找失败。

#include<bits/stdc++.h>
using namespace std;typedef struct {int key;//查找表中数据的值//按需求添加其他属性
}ElemType;typedef struct {ElemType *elem;//存放查找表中数据元素的数组int length;//记录查找表中的数据总数量
}SSTable;
//创建查找表
void Creat(SSTable **st,int length) {(*st) =(SSTable*) new SSTable;(*st)->length = length;(*st)->elem = (ElemType *) new ElemType[length + 1];//根据查找表中数据元素的总长度,在存储时,从数组下标为 1 的空间开始存储数据cout << "输入表中元素:\n";for (int i = 1; i <= length; ++i) {cin >> ((*st)->elem[i].key);}
}
//查找表查找的功能函数,其中key为关键字
int Search_seq(SSTable *st, int key) {st->elem[0].key = key;//将关键字作为一个数据元素存放在查找表的第一个位置,监视哨作用int i = st->length;//从查找表的最后一个元素依次遍历,直到下标为0while (st->elem[i].key != key)i--;//如果 i=0,说明查找失败;反之,返回的是含有关键字key的数据元素在查找表中的位置return i;
}int main() {SSTable *st;Creat(&st, 6);getchar();printf("请输入查找数据的关键字:\n");int key;cin >> key;int location = Search_seq(st, key);if (location == 0) {printf("查找失败\n");}else {printf("数据在查找表中的位置为:%d", location);}return 0;
}
输入表中的数据元素:
1 2 3 4 5 6
请输入查找数据的关键字:
2
数据在查找表中的位置为:2

使用监视哨对普通的顺序表的遍历算法做了改进,在数据量大的情况下,能够有效提高算法的运行效率。


二分查找(折半查找)算法

折半查找,也称二分查找,在某些情况下相比于顺序查找,使用折半查找算法的效率更高。但是该算法的使用的前提是静态查找表中的数据必须是有序的。

例如,在{5,21,13,19,37,75,56,64,88 ,80,92}这个查找表使用折半查找算法查找数据之前,需要首先对该表中的数据按照所查的关键字进行排序:{5,13,19,21,37,56,64,75,80,88,92}

在折半查找之前对查找表按照所查的关键字进行排序的意思是:若查找表中存储的数据元素含有多个关键字时,使用哪种关键字做折半查找,就需要提前以该关键字对所有数据进行排序。

#include<bits/stdc++.h>
using namespace std;
#define MAX_INT 20//int a[MAX_INT];//存储元素
int n;//数组大小int BinarySearch(int a[], int value) {int left = 0;int right = n - 1;while (left <= right) {//最好改用位运算符而不是 /2 //https://www.cnblogs.com/Kanna/p/12371164.html  (位运算详解)    if (value > a[(left + right) / 2])left = (right + left) / 2;else if (value < a[(left + right) / 2])right = (right + left) / 2;else{return (left + right) / 2;}}return -1;
}int main() {int a[] = { 1,2,3,4,5 };//sorted arraysn = 5;int ans = BinarySearch(a, 3);if (ans == -1)cout << " Not find " << endl;else cout << ans + 1 << endl;return 0;
}

注意:在做查找的过程中,如果 left 和 right 的中间位置在计算时位于两个关键字中间,即求得 mid 的位置不是整数,需要统一做取整操作。

通过比较折半查找的平均查找长度,同前面介绍的顺序查找相对比,明显折半查找的效率要高。但是折半查找算法只适用于有序表,同时仅限于查找表用顺序存储结构表示。

当查找表使用链式存储结构表示时,折半查找算法无法有效地进行比较操作(排序和查找操作的实现都异常繁琐)。


分块查找(索引顺序查找)算法

分块查找,也叫索引顺序查找,算法实现除了需要查找表本身之外,还需要根据查找表建立一个索引表。例如图 1,给定一个查找表,其对应的索引表如图所示:

图中,查找表中共 18 个查找关键字,将其平均分为 3 个子表,对每个子表建立一个索引,索引中包含中两部分内容:该子表部分中最大的关键字以及第一个关键字在总表中的位置,即该子表的起始位置。

建立的索引表要求按照关键字进行升序排序,查找表要么整体有序,要么分块有序。

分块有序指的是第二个子表中所有关键字都要大于第一个子表中的最大关键字,第三个子表的所有关键字都要大于第二个子表中的最大关键字,依次类推。

块(子表)中各关键字的具体顺序,根据各自可能会被查找到的概率而定。如果各关键字被查找到的概率是相等的,那么可以随机存放;否则可按照被查找概率进行降序排序,以提高算法运行效率。

分块查找的具体实现

所有前期准备工作完成后,开始在此基础上进行分块查找。分块查找的过程分为两步进行:

  1. 确定要查找的关键字可能存在的具体块(子表);
  2. 在具体的块中进行顺序查找。

以图中的查找表为例,假设要查找关键字 38 的具体位置。首先将 38 依次和索引表中各最大关键字进行比较,因为 22 < 38 < 48,所以可以确定 38 如果存在,肯定在第二个子表中。

由于索引表中显示第二子表的起始位置在查找表的第 7 的位置上,所以从该位置开始进行顺序查找,一直查找到该子表最后一个关键字(一般将查找表进行等分,具体子表个数根据实际情况而定)。结果在第 10 的位置上确定该关键字即为所找。

Tip:在第一步确定块(子表)时,由于索引表中按照关键字有序,所有可以采用折半查找算法。而在第二步中,由于各子表中关键字没有严格要求有序,所以只能采用顺序查找的方式。

具体实现代码:

#include<bits/stdc++.h>
using namespace std;struct index {  //定义块的结构int key;int start;
} newIndex[3];   //定义结构体数组
int search(int key, int a[]);
int cmp(const void *a, const void* b) {return (*(struct index*)a).key > (*(struct index*)b).key ? 1 : -1;
}
int main() {int i, j = -1, k, key;int a[] = { 33,42,44,38,24,48, 22,12,13,8,9,20,  60,58,74,49,86,53 };//确认模块的起始值和最大值for (i = 0; i < 3; i++) {newIndex[i].start = j + 1;  //确定每个块范围的起始值j += 6;for (int k = newIndex[i].start; k <= j; k++) {if (newIndex[i].key < a[k]) {newIndex[i].key = a[k];}}}//对结构体按照 key 值进行排序qsort(newIndex, 3, sizeof(newIndex[0]), cmp);//输入要查询的数,并调用函数进行查找printf("请输入您想要查找的数:\n");scanf("%d", &key);k = search(key, a);//输出查找的结果if (k > 0) {printf("查找成功!您要找的数在数组中的位置是:%d\n", k + 1);}else {printf("查找失败!您要找的数不在数组中。\n");}return 0;
}
int search(int key, int a[]) {int i, startValue;i = 0;while (i<3 && key>newIndex[i].key) { //确定在哪个块中,遍历每个块,确定key在哪个块中i++;}if (i >= 3) {  //大于分得的块数,则返回0return -1;}startValue = newIndex[i].start;  //startValue等于块范围的起始值while (startValue <= startValue + 5 && a[startValue] != key){startValue++;}if (startValue > startValue + 5) {  //如果大于块范围的结束值,则说明没有要查找的数return -1;}return startValue;
}
请输入您想要查找的数:
22
查找成功!您要找的数在数组中的位置是:7

分块查找的性能分析

分块查找算法的运行效率受两部分影响:

查找块的操作和块内查找的操作。查找块的操作可以采用顺序查找,也可以采用折半查找(更优);块内查找的操作采用顺序查找的方式。相比于折半查找,分块查找时间效率上更低一些;相比于顺序查找,由于在子表中进行,比较的子表个数会不同程度的减少,所有分块查找算法会更优。

总体来说,分块查找算法的效率介于顺序查找和折半查找之间。


http://chatgpt.dhexx.cn/article/3n2Eby3R.shtml

相关文章

数据结构 第八章 查找(静态查找表)

集合 1、集合中的数据元素除了属于同一集合外,没有任何的逻辑关系 2、在集合中,每个数据元素都有一个区别于其他元素的唯一标识(键值或者关键字值) 3、集合的运算&#xff1a; 1 查找某一元素是否存在(内部查找、外部查找) 2 将集合中的元素按照它的唯一标识进行排序4、集合的…

9.1 查找表:静态查找表

9.1 查找表&#xff1a;静态查找表. 9.2 查找表&#xff1a;动态查找表. 9.3 查找表&#xff1a;哈希表. 9.1 查找表&#xff1a;静态查找表 1 基本概念2 抽象数据类型3 顺序查找表3.1 顺序存储结构模块中的实现3.2 分析顺序查找的时间性能. 4 有序查找表4.1 代码实现4.2 折半查…

数据结构----查找表

前言 突然发现自己过得茫茫然&#xff0c;学过的东西&#xff0c;似懂非懂&#xff0c;不知所以。昨晚打开以前瞎写 的博客&#xff0c;又来了兴趣。 人在反思中成长&#xff0c;在总结中进步。加油&#xff01;目录 前言 查找表 正文静态查找表顺序查找表有序查找表索引查找表…

sql server查找表的字段信息

查找表的字段信息 SELECT (case when a.colorder1 then d.name else end) N表名, a.colorder N字段序号, a.name N字段名, (case when COLUMNPROPERTY( a.id,a.name,IsIdentity)1 then √else end) N标识, (case when (SELECT count(*) FROM sysobjects WHERE (name in (SEL…

算法——查找表

查找&#xff0c;根据一个值查找另一个值&#xff0c;value值可以是容器&#xff0c;结构&#xff0c;这样可查找的元素就更多&#xff1b; 哈希冲突&#xff1a; 主关键字&#xff1a;可以唯一的标识一个记录的关键字&#xff0c;如准考证号&#xff1b; 此关键词&#xff…

LUT 查找表(Look-Up-Table)

LUT就是查找表&#xff0c;对于4输入的LUT而言&#xff0c;实际上就是4位地址位&#xff0c;一位数据位的存储器&#xff0c;能够存储16位数据&#xff0c;所以我们在FPGA设计中可以用LUT组建分布式的RAM。 如果用传统的逻辑来实现一个4输入的逻辑电路&#xff0c;需要大致三个…

查找表(LUT,Look-up Table)的简单理解

查找表&#xff08;LUT&#xff0c;Look-up Table&#xff09;的简单理解 引入&#xff1a;假设有一个 4 输入(a,b,c,d) 1 输出(o) 的逻辑单元&#xff0c;想要了解其内部结构。 输入按照 0000-1111 去遍历&#xff0c;记录输出。得到真值表&#xff0c;运用卡诺图对其化简&a…

查找表算法

查找表是由同一类型的数据元素构成的集合。 一般对于查找表有一下几种操作&#xff1a; 1、在查找表中查找某个具体的数据元素&#xff1b; 2、在查找表中插入数据元素&#xff1b; 3、从查找表中删除数据元素。静态查找表和动态查找表在查找表中只做查找操作&#xff0c;不带动…

数据结构之查找表

前言 今天学习数据结构看到了一个词-静态查找表&#xff0c;还有与之对应的动态查找表&#xff0c;然后我发现。 啊&#xff0c;这是个啥&#xff0c;好像知道又好像不知道&#xff0c;不就是查找吗&#xff0c;干嘛弄这些专业的说法&#xff0c;回头翻了一下数据结构的书&am…

数据结构查找表详解(包含常用查找算法)

** 1. 什么是查找表 ** 在日常生活中&#xff0c;几乎每天都要进行一些查找的工作&#xff0c;在电话簿中查阅某个人的电话号码&#xff1b;在电脑的文件夹中查找某个具体的文件等等。本节主要介绍用于查找操作的数据结构——查找表。 查找表是由同一类型的数据元素构成的集…

FPGA工作原理

一.查找表&#xff08;Look-Up-Table)的原理与结构 采用这种结构的PLD芯片我们也可以称之为FPGA&#xff1a;如altera的ACEX,APEX系列,xilinx的Spartan,Virtex系列等。 查找表&#xff08;Look-Up-Table)简称为LUT&#xff0c;LUT本质上就是一个RAM。 目前FPGA中多使用4输入的…

FPGA知识积累【3】

目录 1.查找表&#xff08;LUT&#xff09;原理与结构2.FPGA基本结构3.FPGA的RAM、ROM、CAM4.硬件语言的层次5.寄生效应6.线与逻辑7.竞争冒险8.消除竞争冒险的方法 1.查找表&#xff08;LUT&#xff09;原理与结构 ①查找表简称LUT&#xff0c;本质上就是一个RAM。目前FPGA中多…

数据结构导论【六】之 查找表

感谢内容提供者&#xff1a;金牛区吴迪软件开发工作室 接上一篇&#xff1a;数据结构导论【五】之 图 文章目录 一、基本概念二、静态查找表的实现1.顺序表上的查找 -- 顺序查找a.过程b.算法c.算法分析 2.有序表上的查找 -- 二分查找a.二分查找思想b.二分查找过程c.二分查找算法…

查找表(Lookup table)

查找表&#xff08;look-up-table&#xff09;这个名字很好听&#xff0c;缩写 LUT&#xff0c;听起来很高端&#xff0c;其实是一种很简单高效的索引操作&#xff0c;今天简单介绍一下。 是啥 wiki定义&#xff1a; a lookup table is an array that replaces runtime computa…

从底层结构开始学习FPGA(2)----LUT查找表

文章目录 系列目录与传送门 一、概述 二、实现原理 系列目录与传送门 《从底层结构开始学习FPGA》目录与传送门 一、概述 记得刚接触FPGA的时候&#xff0c;总能看见类似这样的一句话----FPGA是基于查找表LUT的可编程逻辑器件。FPGA常常被人比作“数字积木”&#xff0c;就是因…

码,主码,主属性,非主属性,平凡函数依赖,完全依赖等词解释

码&#xff1a;代表数目的符号 主码 我们在建立数据库的时候&#xff0c;需要为每张表指定一个主码&#xff0c;主码也叫主键。 所谓主码就是在实体集中区分不同实体的候选码。 一个实体集中只能有一个主码&#xff0c;但可以有多个候选码。 必须注意两点&#xff1a; 1.主…

SpringBoot项目打jar后执行jar包提示:xx没有主属性清单 解决

SpringBoot项目打jar包后执行jar包提示&#xff1a;xx没有主属性清单 解决 今天在练习SpringBoot项目打jar包部署的时间遇见了一个问题&#xff1a;jar中没有主属性清单&#xff0c;对此也是比较疑惑&#xff0c;在百度之后找到了解决方式 主属性清单是jar包中MANIFEST.MF文件中…

【图示化】SQL Server概念:超键(码)、候选键(候选码)、主键(主码)、主属性与非主属性、外键

关系模型概念 字段属性名&#xff0c;每一行就是一条记录一个元组&#xff0c;每个单元格就是一个分量&#xff0c; 主键&#xff0c;外键 主码主键主关键字 超键&#xff08;码&#xff09;&#xff0c;候选键 码超键 超键 &#xff08;唯一的&#xff0c;可多余&#xff09; …

候选码、主码、全码、外码、主属性、主键、主关键字、非主属性

一、讲解 首先说明 键字码字&#xff0c;所以 主键主码主关键字&#xff0c;候选键候选码候选关键字… 所谓关系键&#xff0c;指的是一个表中的一个&#xff08;或一组&#xff09;属性&#xff0c;用来标识该表的每一行或与另一个表产生联系。 话不多说&#xff0c;上图&a…

软考系列之候选码,主码,主属性,非主属性详讲

候选码&#xff0c;主码&#xff0c;主属性&#xff0c;非主属性详讲 文章目录 目录 文章目录 前言 一、候选码&#xff0c;主码&#xff0c;属性&#xff0c;非主属性的定义 二、具体题目 三、补充 前言 软考刷题&#xff0c;遇到这系列的题目&#xff0c;对我来讲&#xff0…