数据结构与算法-静态查找表

在这里插入图片描述
🌞 “清醒 自律 知进退!”

查找

  • 🎈1.查找的相关概念
  • 🎈2.静态查找表
    • 🔭2.1静态查找表的类定义
    • 🔭2.2顺序查找
    • 🔭2.3二分查找
      • 🔎二分查找例题
    • 🔭2.4分块查找
    • 🔭2.5三种算法的比较分析

查找是在一些有序的或无序的数据元素中,通过一定的方法找出与给定关键字相同的数据元素的过程,即根据给定的某个值在查找表中确定一个关键字等于给定的记录或数据元素。查找是信息处理科学中十分重要的操作。

🎈1.查找的相关概念

  1. 查找表是同一类型数据元素(或记录)构成的集合,与4种数据关系中的集合结构对应。由于集合中数据元素之间存在着完全松散的关系。因此,查找表往往要借助其他数据结构来实现相关算法。
  2. 关键字是可以标识一个数据元素(或记录)的数据项,关键字的值被称之为键值。若关键字可以唯一地标识一条记录,则称此关键字为主关键字。
  3. 查找是根据给定的某个值,在查找表中确定一个关键字等于给定值的记录或数据元素的过程。若在查找表中存在与给定值匹配的记录,则查找成功,此时查找的结果可以是整个记录的信息或查找成功标记等。若在查找表中不存在与给定值匹配的记录,则查找不成功,此时查找结果可以是不成功标记,或将被查找记录插入查找表。
  4. 静态查找表是仅对表进行查找操作,而不进行插入和删除操作的查找表。静态查找在查找不成功时,只返回一个不成功标志,不改变查找表,因此表中数据元素的数量不会发生变化。
  5. 动态查找表是在查找的同时对表进行插入和删除操作的表。动态查找在查找不成功时,需要将被查找的记录插入查找表,因此表中数据元素的数量可能会发生变化。
    在这里插入图片描述

🎈2.静态查找表

🔭2.1静态查找表的类定义

#define _CRT_SECURE_NO_WARNINGS 1
#define Max 100
#include <iostream>
using namespace std;
typedef int KeyType;
typedef int InfoType;
typedef int IndexType;
typedef struct 
{KeyType key;//KeyType为关键字数据类型InfoType otherinfo;//其他域
}SElemType;
class StaticSearchtable
{
private:SElemType* elem;int length;
public:StaticSearchtable()//构造函数,0位留空{elem = new SElemType[Max + 1];length = 0;}~StaticSearchtable()//析构函数,释放存储空间{delete[]elem;length = 0;}void Create(int n)//创建n个元素的顺序表{for (int i = 0; i <= n; i++){cin >> elem[i].key >> elem[i].otherinfo;}length = n;}int SqSearch(KeyType key);//顺表表查找值等于key的关键字int BinSearch(KeyType key);//二分查找值等于key的关键字int IndexSearch(IndexType index[Max], KeyType key, int b);//分块查找值等于key的关键字,b为块数
};

🔭2.2顺序查找

🔎顺序查找的主要思想

  1. 设立哨兵位elem[0].key=key,其作用是防止扫描溢出。
  2. 从表的末端开始向左扫描线性表,依次将扫描到的关键字值和给定值key进行比较,若找到关键字,则查找成功,返回该关键字在顺序表中的下标;否则查找失败,返回0.
int StaticSearchtable::SqSearch(KeyType key)
{elem[0].key = key;//哨兵位int i = 0;for (i = length; elem[i].key != key; i--)//从末端开始向左扫描{;//空语句}return i;
}

🔎顺序查找分析:
在这里插入图片描述

🔭2.3二分查找

二分查找又称折半查找,它是一种效率较高的查找方法。二分查找要求线性表采用顺序存储结构且元素有序。类似于顺序查找方法,在存储元素时,数组元素第0位留空。

🔎二分查找的主要思想是每次将待查找记录所在的区间缩小一 半。具体步骤如下:设elem[low..high]是当前的查找区间,首先确定中间点位置mid = [(low+high)/2],然后将待查元素的关键字key值与elem[mid].key比较:(初始时,令low=1,high=length

  1. mid = [(low+high)/2]
  2. key==elem[mid].key,则查找成功,返回mid,即该元素在顺序表中的下标。
  3. key<elem[mid].key,则high = mid-1
  4. key>elem[mid].key,则low = mid+1
  5. 重复上述操作,直至low>high时,查找失败,此时返回0
int StaticSearchtable::BinSearch(KeyType key)
{int low = 1,high = length;int mid;while (low <= high){mid = (low + high) / 2;if (key == elem[mid].key)return mid;else if (key < elem[mid].key)high = mid - 1;elselow = mid + 1;}return 0;
}

✅二分查找过程可用二叉树来描述,在构造二叉树的过程中,把当前查找区间的中点位置上的元素作为树根,左子表和右子表的元素分别作为根的左子树和右子树。由此递归得到二叉树,通常称描述查找的过程的二叉树为判定树。判定树的形态与表中个数n相关,与输入示例中的key值无关。

例如,要找到15个数据元素的有序表中的第8个元素仅需比较1次,找到第4和第12个元素需要比较2次,找到第2,6,1014个元素需要比较3次;找到第1,3,5,7,9,11,1315个元素需要比较4次。其查找过程如图所示,树中的每个圆圈结点表示表中一个元素,结点中的值表示该元素在表中的位置;圆圈结点表示查找成功,方框结点表示查找失败。若查找失败,则比较过程是一条从判定树的根到某结点的路径,所需关键字比较次数是该路径上圆圈结点的个数。
在这里插入图片描述

🔎二分查找分析:

  1. 判定树为满二叉树:(有序表元素个数为:n=2h-1
    (1).查找成功时平均查找长度:
    在这里插入图片描述
    (2).查找不成功时平均查找长度:h

  2. 判定树为非满二叉树:

(1).查找成功时平均查找长度:
在这里插入图片描述
(2).查找不成功时平均查找长度:
在这里插入图片描述

🔎二分查找例题

例:给定18个元素的有序表 {2,5,8,10,15,40,42,55,66,70,72,75,80,88,90,100,108,200},采用二分查找,试问:
(1).查找长度为4和5的元素个数分别有多少个?
(2).若要查找值为15的数据元素,要经过多少次比较?依次与哪些元素进行比较?
(3).在查找概率相等的情况下,计算查找成功和查找不成功的平均查找长度。
在这里插入图片描述
:第一问可以直接数第四行和第五行元素的个数:分别是8和3.
第二问数这条路径圆圈结点的个数为比较次数,圆圈内的值为比较的数:
在这里插入图片描述
因此,我们需要进行4次比较,依次与表中的元素66,10,40,15比较。
第三问,在查找概率相等的情况下,查找成功的平均查找长度为:
(11+22+43+84+35)/18=32/9
查找不成功的平均查找长度为:(4
13+5*6)/19=82/19

🔭2.4分块查找

🔎 分块查找又称索引顺序查找,它是顺序表查找的一种改进方法,其性能介于顺序查找和二分查找之间。在索引查找方法中,除存储表本身以外,还需存储一个索引表。存储方法如下:

  1. 将线性表elem[1..n]均分为b块,前b-1块中元素个数为s=[n/b],最后一块即b块的元素个数小于等于s.
  2. 每一块中的关键字不一定有序,但前一块中的最大关键字小于后一块中的最小关键字,即块内无序,块间有序
  3. 抽取各块的最大关键字及起始位置构成一个索引表index[0..b-1],即index[i](0<=i<=b-1)中存放第i块的最大关键字和该块在表中的初始位置。

📖索引表的数据类型定义:

typedef struct
{KeyType key;int link;
}IndexType;

📖分块查找的算法:

int StaticSearchtable::IndexSearch(IndexType index[Max], KeyType key, int b)
{//b为块数int low = 0, high = b - 1, mid, i, s;if (length % b == 0)s = length / b;elses = length / b + 1;while (low <= high){mid = (low + high) / 2;if (index[mid].key >= key)high = mid - 1;elselow = mid + 1;}//在索引表high+1快对应的线性表中顺序查找keyi = index[high + 1].link;while (i <= index[high + 1].link + s - 1 && elem[i].key != key){i++;}if (i <= index[high + 1].link + s - 1)return i;//查找成功,返回该元素的下标elsereturn 0;//查找失败,返回0
}

🔭2.5三种算法的比较分析

  1. 顺序查找的时间复杂度最差,二分查找的时间复杂度最好,分块查找的时间复杂度介于两种之间。
  2. 分块查找需要增加索引数据的空间,空间复杂度最大。
  3. 顺序查找对表没有特殊要求。
  4. 分块查找的数据块之间在物理上可以不连续,插入、删除数据只涉及对应的块,但增加了索引的维护。
  5. 二分查找要求表有序,若表的元素插入与删除很频繁,则维持有序的工作量极大。
  6. 在表不大的时候,一般使用顺序查找。

🌞运行示例:

#define _CRT_SECURE_NO_WARNINGS 1
#define Max 100
#include <iostream>
using namespace std;
typedef int KeyType;
typedef int InfoType;
typedef struct
{KeyType key;//KeyType为关键字数据类型InfoType otherinfo;//其他域
}SElemType;
typedef struct
{KeyType key;int link;
}IndexType;
class StaticSearchtable
{
private:SElemType* elem;int length;
public:StaticSearchtable()//构造函数,0位留空{elem = new SElemType[Max + 1];length = 0;}~StaticSearchtable()//析构函数,释放存储空间{delete[]elem;length = 0;}void Create(int n)//创建n个元素的顺序表{for (int i = 0; i <= n; i++){cout << "输入第" << i+1 << "个元素的值和下标:";cin >> elem[i].key >> elem[i].otherinfo;}length = n;}int SqSearch(KeyType key);//顺表表查找值等于key的关键字int BinSearch(KeyType key);//二分查找值等于key的关键字int IndexSearch(IndexType index[Max], KeyType key, int b);//分块查找值等于key的关键字,b为块数
};
int StaticSearchtable::SqSearch(KeyType key)
{elem[0].key = key;//哨兵位int i = 0;for (i = length; elem[i].key != key; i--)//从末端开始向左扫描{;//空语句}if (i >= 0)cout << "该数所在顺序表中的下标为:" << i << endl;elsecout << "未找到!" << endl;return 0;
}
int StaticSearchtable::BinSearch(KeyType key)
{int low = 1, high = length;int mid;while (low <= high){mid = (low + high) / 2;if (key == elem[mid].key){cout << "该数经二分查找下标为:" << mid << endl;break;}else if (key < elem[mid].key)high = mid - 1;elselow = mid + 1;}if(low>high)cout << "未找到!" << endl;return 0;
}
int StaticSearchtable::IndexSearch(IndexType index[Max], KeyType key, int b)
{//b为块数int low = 0, high = b - 1, mid, i, s;if (length % b == 0)s = length / b;elses = length / b + 1;while (low <= high){mid = (low + high) / 2;if (index[mid].key >= key)high = mid - 1;elselow = mid + 1;}//在索引表high+1快对应的线性表中顺序查找keyi = index[high + 1].link;while (i <= index[high + 1].link + s - 1 && elem[i].key != key){i++;}if (i <= index[high + 1].link + s - 1)return i;//查找成功,返回该元素的下标elsereturn 0;//查找失败,返回0
}
int main()
{StaticSearchtable a;a.Create(8);a.SqSearch(6);a.BinSearch(7);return 0;
}

在这里插入图片描述

好啦,关于静态查找表的知识到这里就先结束啦,后期会继续更新学习数据结构与算法的相关知识,欢迎大家持续关注、点赞和评论!❤️❤️❤️

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/190868.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

理解BatchNormalization层的作用

深度学习 文章目录 深度学习前言一、“Internal Covariate Shift”问题二、BatchNorm的本质思想三、训练阶段如何做BatchNorm四、BatchNorm的推理(Inference)过程五、BatchNorm的好处六、机器学习中mini-batch和batch有什么区别 前言 Batch Normalization作为最近一年来DL的重…

logistic回归详解

为什么不直接统计标签数和预测结果数&#xff0c;计算精度&#xff1f; 因为 存在梯度为0的情况梯度不连续 为什么叫logistic回归 logistic是因为加了一个sigmoid函数&#xff0c;将输出预测值映射到【0&#xff0c;1】 有时候使用MSE损失函数&#xff0c;拟合 有时候使用c…

selenium三猛士

selenium包括三个项目&#xff0c;分别是&#xff1a;Selenium WebDriver,Selenium IDE&#xff0c;Selenium Grid。 Selenium WebDriver Selenium WebDriver是客户端API接口&#xff0c;测试人员通过调用这些接口&#xff0c;来访问浏览器驱动&#xff0c;浏览器再访问浏览器…

利用Python中的Manim进行数学绘画和创作

相信很多同学就算没听过3Blue1Brown&#xff0c;也一定曾看过他们出品的视频&#xff0c;其从独特的视觉角度解说各种数学概念&#xff0c;内容包括线性代数、微积分、神经网络、傅里叶变换以及四元数等晦涩难懂的知识点。例如最火的《线性代数本质》系列视频。 那么这些视频是…

【算法】动态规划中的路径问题

君兮_的个人主页 即使走的再远&#xff0c;也勿忘启程时的初心 C/C 游戏开发 Hello,米娜桑们&#xff0c;这里是君兮_&#xff0c;如果给算法的难度和复杂度排一个排名&#xff0c;那么动态规划算法一定名列前茅。今天&#xff0c;我们通过由简单到困难的两道题目带大家学会动…

文字、图片免费生成视频和专属数字人,你不来试试吗?

查看生成的效果&#xff1a;AI产生的视频&#xff08;关注公众号&#xff0c;获取精彩内容&#xff09; 您是否想要制作一些令人惊叹的视频&#xff0c;但又没有视频编辑的技能或经验&#xff1f;您是否想要利用人工智能的力量&#xff0c;让您的图片和声音变成动态的视频&…

如何强制任何Android应用程序进入全屏沉浸式模式(无生根)

谷歌在2012年发布了Android版本的Chrome&#xff0c;并且从未费心给它一个全屏模式。如果您厌倦了等待自己喜欢的Android应用程序提供全屏&#xff0c;则可以使用沉浸式模式自行完成。 来吧&#xff0c;谷歌&#xff0c;我真的一直在乞求你多年&#xff01;没有理由不给我们一…

【Go语言反射reflect】

Go语言反射reflect 一、引入 先看官方Doc中Rob Pike给出的关于反射的定义&#xff1a; Reflection in computing is the ability of a program to examine its own structure, particularly through types; it’s a form of metaprogramming. It’s also a great source of …

C语言——深入理解指针(4)

目录 1.回调函数 2. qsort 函数的使用 2.1 排序整型数据 2.2 排序结构体数据 3. qsort 函数的模拟实现 1.回调函数 回调函数就是通过一个函数指针调用的函数。 你把函数的地址作为参数传递给另一个函数&#xff0c;当这个指针被用来调用其所指向的函数时&#xff0c;被调…

【web安全】ssrf漏洞的原理与使用

前言 菜某对ssrf漏洞的总结。 ssrf的作用 主要作用&#xff1a;访问外界无法访问的内网进行信息收集。 1.进行端口扫描&#xff0c;资源访问 2.指纹信息识别&#xff0c;访问相应的默认文件 3.利用漏洞或者和payload进一步运行其他程序 4.get类型漏洞利用&#xff0c;传参数…

用CHAT 写一份销售人员激励方案

问CHAT &#xff1a;写一份销售人员早会激励方案 CHAT回复&#xff1a; 标题&#xff1a;鼓舞斗志&#xff0c;迎接新的一天 -- 销售人员早会激励方案 一、会议的氛围设定&#xff1a; 深呼吸&#xff0c;准备开始一天的事业&#xff1a;清晨的阳光&#xff0c;温暖而明亮&…

Nat. Rev. Chem. | 一份关于用机器学习研究化学问题的评估指导

今天为大家介绍的是来自Tiago Rodrigues团队的一篇论文。机器学习&#xff08;ML&#xff09;有望解决化学领域的重大挑战。尽管ML工作流程的适用性极广&#xff0c;但人们通常发现评估研究设计多种多样。目前评估技术和指标的异质性导致难以&#xff08;或不可能&#xff09;比…

Android BT HCI分析简介

对于蓝牙开发者来说&#xff0c;通过HCI log可以帮助我们更好地分析问题&#xff0c;理解蓝牙协议&#xff0c;就好像网络开发一定要会使用Wireshark分析网络协议一样。 本篇主要介绍HCI log的作用、如何抓取一份HCI log&#xff0c;并结合一个实际的例子来说明如何分析HCI log…

亚马逊云科技 re:Invent 2023:科技前沿风向标,探索未来云计算之窗

文章目录 一、前言二、什么是亚马逊云科技 re:Invent&#xff1f;三、亚马逊云科技 re:Invent 2023 将于何时何地举行四、亚马逊云科技 re:Invent 2023 有什么内容&#xff1f;4.1 亚马逊云科技 re:Invent 2023 主题演讲4.2 亚马逊云科技行业专家探实战 五、更多亚马逊云科技活…

单片机----汇编语言入门知识点

目录 汇编语句的格式 汇编语句的两个基本语句 子程序的调用 查表程序设计 1.x和y均为单字节数的查表程序设计 2.x为单字节数y为双字节数的查表程序设计 3.x和y均为双字节数的查表程序设计 分支转移程序设计 1.单分支选择结构 2.多分支选择结构 循环程序设计 (1) 计…

华为1+x网络系统建设与运维(中级)-练习题2

一.设备命令 LSW1 [Huawei]sys LSW1 同理可得&#xff0c;给所有设备改名 二.VLAN LSW1 [LSW1]vlan ba 10 20 [LSW1]int g0/0/1 [LSW1-GigabitEthernet0/0/1]port link-type trunk [LSW1-GigabitEthernet0/0/1]port trunk allow-pass vlan 10 20 [LSW1-GigabitEthernet0/0/1]in…

根目录/ 空间不够,扩容,导致web页面无法加载问题

现象就是&#xff1a;搭建的web页面无反应&#xff0c;也没报错&#xff0c;怀疑是内存空间不够导致的。/ 扩容步骤如下&#xff1a; 虚拟机为关机状态添加虚拟磁盘 #查看磁盘&#xff0c;并创建新分区 fdisk -l fdisk /dev/sdb p       查看已分区数量&#xff08;我看…

SQL Server 数据库,为products表添加数据

在插入数据的时候&#xff0c;需要注意以下事项。 > 每次插入一整行数据&#xff0c;不可能只插入半行或几列数据。 > 数据值的数目必须与列数相同&#xff0c;每个数据值的数据类型、精度和小数位数也必须与相应的 列匹配。 > INSERT语句不能为标识列指定值&#…

触控板绘画工具Inklet mac功能介绍

Inklet mac是一款触控板绘画工具&#xff0c;把你的触控板变成画画的板子&#xff0c;意思是&#xff0c;你点在触控板的哪里&#xff0c;鼠标就会出现载相应的地方。例如&#xff0c;但你把手指移动到触控盘左下角&#xff0c;那么鼠标也会出现在左下角&#xff0c;对于用户而…

虽有局限性,但在Windows 11上运行Android应用程序是一个不错的新功能

在Windows 11上,Android的Windows子系统(WSA)是一个集成,允许你在笔记本电脑或台式机上与Windows应用程序一起运行Android应用程序,在本指南中,我将向你展示入门步骤。官方规定,你只能从亚马逊应用商店安装应用程序,但也可以使用安卓调试桥(ADB)工具侧载安卓应用程序…