数据结构与算法基础(王卓)(26)线性表的查找(2):顺序查找(二分查找、分块查找)

news2024/11/14 13:23:24

二、折半查找(二分或对分查找)

前置条件和前面一样

最开始根据PPT示(实)例写出的程序框架:

一开始:

low:第一位

high:最后一位

mid:正中间

查找数小于mid:

把high移动到mid前面一位( - 1)

再取新mid = 新【正中间】

查找数大于mid:

把low移动到mid后面一位( + 1)

再取新mid = 新【正中间】

然而这里,我写的只是一些框架的核心规则,并没有梳理出程序具体是怎么运行的逻辑流程

所以写的和标准答案写的不一样:

Project 1:

int Seaarch_Bin(SSTable ST, KeyType key)
//binary:二进制的; 仅基于两个数字的; 二元的; 由两部分组成的;
{
    int low = 1, high = ST.length, mid = (low + high) / 2;
    while (key != mid)
    {
        if (key < mid)
        {
            high = mid - 1;
            mid = (low + high) / 2;
        }
        else if (key < mid)
            //else
        {
            low = mid + 1;
            mid = (low + high) / 2;
        }
    }
    if (low > high)
        return false;
    else
        return mid;
}

里面除了梳理逻辑以外,还存在另外的诸多问题,当然:

写程序之前最好肯定还是梳理出程序具体是怎么运行的逻辑流程,这是肯定的

上面这一版本还存在着诸多的问题:

  • key在比较时不应该写【mid】应改成【ST.R[mid].key】(Project 2中我们会对此作出具体详细的剖析解释)
  • while循环当中无论是在哪种情况(分支),(都)始终执行【mid = (low + high) / 2;】语句,应当(可以)考虑合并语句在【if】语句之外

修正后的结果如下:

(我觉得修改成如下结果以后,这个结果写的也没有错,只不过我没有那么确定一定没错)

int Seaarch_Bin(SSTable ST, KeyType key)
//binary:二进制的; 仅基于两个数字的; 二元的; 由两部分组成的;
{
    int low = 1, high = ST.length, mid = (low + high) / 2;
    while (key != ST.R[mid].key)
    {
        if (key < ST.R[mid].key)
            high = mid - 1;
        else if (key < ST.R[mid].key)//else
            low = mid + 1;
        mid = (low + high) / 2;
    }
    if (low > high)
        return false;
    else
        return mid;
}

除此之外,我们首当其冲要做的:就是要梳理出程序具体是怎么运行的逻辑流程

把程序转换为和PPT上类似的逻辑形式:(但是这并不代表我写的是错的)

Project 2:

int Seaarch_Bin(SSTable ST, KeyType key)
//binary:二进制的; 仅基于两个数字的; 二元的; 由两部分组成的;
{
    //不是从R开始吗???
    int low = 1, high = ST.length, mid = (low + high) / 2;
    while (low<=high)
        //一开始我们是想写(key != mid)的判断语句的,但是如果这样写的话我们最后就无法判断他有没有找到
    {
        if (key = mid)
            return mid;
        else if (key < mid)
        {
            high = mid - 1;
            mid= (low + high) / 2;
        }
        else if (key > mid)
            //else
        {
            low = mid + 1;
            mid = (low + high) / 2;
        }
    }
    return 0;
}

问题(1):【ST.R[mid].key】

key在比较时不应该写【mid】应改成【ST.R[mid].key】

(Project 1中也有类似一样的问题)

具体解释:


首先,我们要意识到:

我们的key要对比的对象,是顺序表ST(数组)内部的具体某个位序(某一格)里面的具体数值

 这个时候我们再去看顺序表的构造,我们就会意识到:

事实上实际顺序表ST和我们原来想当然的写的程序的东西不一样

typedef int KeyType;

//数据元素类型定义

struct ElemType

{

    KeyType key;  //关键字域

    //...           //其他域

};

struct SSTable

    //Sequential Search Table

{

    ElemType* R;  //表基址

    int length;   //表长

}; 

SSTable ST;  //定义顺序表ST

实际上,我们前面写程序的效果是:

让【key】和【指针指向的元素位序序号】去比较

而我们实际需要实现的效果是:

让【key】和【指针指向的元素数据】去比较

而这个KeyType元素数据(关键字数据),则在:

表基址R(虽然我也不知道这个表基址是什么玩意)的关键字域key当中

加上数据类型:

在【(ElemType*)类型的】表基址R【(KeyType)类型的】关键字域key当中

所以,mid应改为:ST.R[mid].key


而这样的解释,实际上也顺带解决了我们在编写程序时:

数组地址顺序不是从R开始吗???

的问题


问题(2):等于:(==)而非(=)


问题(3):关于除、除以、整除

一、关于除和除以的区别:

6除以2:divided by

6÷2=3

6除2:divide

2÷6=⅓

2除6:divide

6÷2=3

2除以6:divided by

2÷6=⅓

二、关于整除的问题:

整除的取整:

取整数,舍去小数

注意:并非四舍五入

在计算机当中,关于除法,只有一个运算符号,那就是“/”

而关于其是否整除:

是表示整除的取整结果【注意:并非四舍五入】还是带小数的最终运算结果,取决于除数和被除数,更准确的说,是除法过程中,所有的运算量

若所有的运算量【所有的 除数和被除数】都为整型(int型):

结果取整,舍去小数(注意:不是四舍五入)

若所有的运算量【所有的 除数和被除数】中只要有一个运算量为实型(实数类型:float、double)

结果保留小数(保留小数位数格式向实数的类型看齐,能更精确就更精确)


问题(4):low等于high时我们应该怎么处理?

在前面的实例中,我们写了low和high大于和小于的情况

那么当low和high等于时我们应该怎么处理?

设计具体实例尝试,假设:

位序123
数据222324
指针lowmidhigh

 所以我们最终得到的结论就是说:

当low等于high时:

如果key不等于【low和high还有mid】,那么就查找失败

如果等于,输出指针

所以对于这个情况,我们还是把他放到while循环里面比较合适


Project 3:(最终结果)

int Seaarch_Bin(SSTable ST, KeyType key)
//binary:二进制的; 仅基于两个数字的; 二元的; 由两部分组成的;
{
    int low = 1, high = ST.length, mid = (low + high) / 2;
    while (low <= high)
    {
        if (key == ST.R[mid].key)
            return mid;
        else if (key < ST.R[mid].key)
            high = mid - 1;
        else if (key > ST.R[mid].key)//else
            low = mid + 1;

        mid = (low + high) / 2;
    }
    return 0;
}

附:

PPT上写的标准答案版本(确实也有可取之处)

他相当于在我们前面写的程序的基础上再简化一步:

一开始不必给mid赋值,只需要在每次循环的开始给mid进行赋值操作即可

int Seaarch_Bin(SSTable ST, KeyType key)
//binary:二进制的; 仅基于两个数字的; 二元的; 由两部分组成的;
{
    int low = 1, high = ST.length,mid; 
    while (low <= high)
    {
        mid = (low + high) / 2;
        if (key == mid)
            return mid;
        else if (key < ST.R[mid].key)
            high = mid - 1;
        else
            //else if (key > ST.R[mid].key)
            low = mid + 1;   
    }
    return 0;
}

PPT上补充:递归实现版本

int Search_bin(SSTable& S, KeyType e, int low, int high)
{
    if (low > high)
        return -1;
    int mid = (high + low) / 2;
    if (e == S.R[mid].key)
        return mid;
    if (e < S.R[mid].key)
        return Search_bin(S, e, low, mid - 1);
    else
        return Search_bin(S, e, mid + 1, high);
}

 平均查找长度推导参考:第五章《树和二叉树》P34

三、分块查找


不考察代码

不过分块查找的代码怎么实现以后有时间倒也可以研究一下,还是挺有意思的

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

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

相关文章

从0搭建Vue3组件库(四): 如何开发一个组件

本篇文章将介绍如何在组件库中开发一个组件,其中包括 如何本地实时调试组件如何让组件库支持全局引入如何在 setup 语法糖下给组件命名如何开发一个组件 目录结构 在packages目录下新建components和utils两个包,其中components就是我们组件存放的位置,而utils包则是存放一些…

观看js编程范式笔记(函数式编程)

js为什么鼓励函数式编程&#xff1f; JavaScript&#xff08;简称 JS&#xff09;是一种面向对象和函数式编程语言&#xff0c;但它在语言层面上更加鼓励函数式编程。以下是几个原因&#xff1a; 函数是一等公民&#xff1a;在 JavaScript 中&#xff0c;函数被视为一等公民&a…

HANA SDA连接外部数据库到BW的步骤

咱都知道&#xff0c;我们不能直接从BW连接到外部数据库。第一步得从HANA database通过SDA去建一个到外部DB的连接。 数据库连接好了&#xff0c;那么接下来别忘了&#xff0c;还得建一个源系统。 也就是说第一步&#xff0c;我们要用HANA SDA通过Linux ODBC driver去连接外部…

Vue3表格(Table)

Vue2表格&#xff08;Table&#xff09; 可自定义设置以下属性&#xff1a; 表格列的配置项&#xff08;columns&#xff09;&#xff0c;类型&#xff1a;Array<{title?: string, width?: number, dataIndex?: string, slot?: string}>&#xff0c;默认 [] 表格数…

史上最全面的苹果公司PMO的运作模式详解

01 苹果公司PMO的发展历程 1. 初期阶段&#xff1a; 在苹果公司刚创立的早期&#xff0c;没有明确的PMO组织。项目经理直接向CEO Steve Jobs汇报&#xff0c;项目管理在公司内部较为分散。 2. 1997年-2001年&#xff1a; 在这段时间内&#xff0c;苹果公司开始成立项目管理…

PasteSpider之关于字符串模板占位字符等的说明

PasteSpider中&#xff0c;构建&#xff0c;部署等都是通过命令执行的&#xff0c;为了更加的灵活&#xff0c;引入了不同的变量&#xff0c;以便适合不同的需求使用。 命令占位符 注&#xff01;&#xff01;&#xff01;&#xff0c;占位符的格式为{{对象.属性}},他们之间没有…

【LeetCode: 1691. 堆叠长方体的最大高度 | 暴力递归=>记忆化搜索=>动态规划】

&#x1f680; 算法题 &#x1f680; &#x1f332; 算法刷题专栏 | 面试必备算法 | 面试高频算法 &#x1f340; &#x1f332; 越难的东西,越要努力坚持&#xff0c;因为它具有很高的价值&#xff0c;算法就是这样✨ &#x1f332; 作者简介&#xff1a;硕风和炜&#xff0c;…

vue2+vue3——42+

vue2vue3——42 vue2 v-cloak指令【14:14】调网速 &#xff1a; no throttling 不让慢 &#xff1b; offline 断网JS 阻塞红色 外部JS &#xff1b; 绿色 网页核心 &#xff1b; 粉色 JS 脚本红色 外部JS 我要走不了&#xff0c; 谁都别想走 &#xff1a; 绿色 不可以渲染到页面…

【安全与风险】互联网协议漏洞

互联网协议漏洞 互联网基础设施TCP协议栈因特网协议&#xff08;IP&#xff09;IP路由IP协议功能(概述)问题:没有src IP认证用户数据报协议&#xff08;UDP&#xff09;传输控制协议 (TCP)TCP报头TCP(三向)握手基本安全问题数据包嗅听TCP连接欺骗随机初始TCP SNs 路由的漏洞Arp…

【OJ比赛日历】快周末了,不来一场比赛吗? #04.15-04.21 #17场

CompHub 实时聚合多平台的数据类(Kaggle、天池…)和OJ类(Leetcode、牛客…&#xff09;比赛。本账号同时会推送最新的比赛消息&#xff0c;欢迎关注&#xff01; 更多比赛信息见 CompHub主页 或 点击文末阅读原文 以下信息仅供参考&#xff0c;以比赛官网为准 目录 2023-04-15&…

openpnp - 顶部相机辅助光的选择

文章目录 openpnp - 顶部相机辅助光的选择概述折腾的过程简易灯板市售的环形灯(不带漫射板)市售的环形灯(不带漫射板) LED单色光调光控制器.市售的环形灯(带漫射板)市售的环形灯(带漫射板) 自己拆解(降低LED灯路数)END openpnp - 顶部相机辅助光的选择 概述 终于将顶部相机…

Debain初始化配置(一)

目录 1.前言 2.简介 3.Debian11 软件包安装与配置 介绍 3.1.Debian 软件包工具 4.Debian11 软件包安装 4.1、更新索引 4.2.软件包升级 4.3.软件包安装 4.4.软件包删除 4.5.软件包清理 5.Debian11 软件包配置 6.Debian11 系统环境初始化 6.1.系统升级 6.2.安装 S…

哈希表——我欲修仙(功法篇)

个人主页&#xff1a;【&#x1f60a;个人主页】 系列专栏&#xff1a;【❤️我欲修仙】 学习名言&#xff1a;莫等闲、白了少年头&#xff0c;空悲切。——岳飞 系列文章目录 第一章 ❤️ 学习前的必知知识 第二章 ❤️ 二分查找 文章目录 系列文章目录什么是哈希表&#xff…

【AIGC】Stable Diffusion原理快速上手,模型结构、关键组件、训练预测方式

【AIGC】Stable Diffusion的建模思想、训练预测方式快速 在这篇博客中&#xff0c;将会用机器学习入门级描述&#xff0c;来介绍Stable Diffusion的关键原理。目前&#xff0c;网络上的使用教程非常多&#xff0c;本篇中不会介绍如何部署、使用或者微调SD模型。也会尽量精简语…

靶机精讲之Tr0ll

主机发现 nmap扫描 端口扫描 UDP扫描 服务扫描 先从ftp和http下手&#xff0c;shh排后 尝试ftp 匿名登录 查看文件下载的信息 wireshark利用读取文件 strings读取 lol.pcap文本 读代码感觉像目录 进行访问 下载 拷贝到目录下&#xff08;记得背后加点&#xff09; file查看文…

Redis五大数据类型

关于Redis的五大数据类型&#xff0c;它们分别为&#xff1a;String、List、Hash、Set、SortSet。本文将会从它的底层数据结构、常用操作命令、一些特点和实际应用这几个方面进行解析。对于数据结构的解析&#xff0c;本文只会从大的方面来解析&#xff0c;不会介绍详细的代码实…

Linux_Shell命令解析

简介 在linux终端中执行ls命令&#xff0c;ls命令是如何被解析并且执行的。Shell命令的格式一般为&#xff1a; [commond] [-options] [parameter]执行命令 命令的选项 命令的参数当执行ls命令是显示当前目录下所有文件的名称 执行ls -l命令是显示当前目录下所有文件的属性…

软件工程开发文档写作教程(01)—开发文档的意义与作用

版权声明 本文原创作者&#xff1a;谷哥的小弟作者博客地址&#xff1a;http://blog.csdn.net/lfdfhl本文参考资料&#xff1a;电子工业出版社《软件文档写作教程》 马平&#xff0c;黄冬梅编著 软件工程开发文档的意义 软件文档是整个软件开发工作的基础&#xff0c;现代工程…

Maven(一)基础入门

目录 一、Maven简介1.背景2.Maven是什么3.Maven的作用 二、下载与安装1.下载2.安装3.配置环境变量 三、Maven基础概念1.仓库2.坐标3.本地仓库配置4.远程仓库配置5.阿里云-镜像仓库配置6.全局 settings 与用户 settings 区别 四、第一个Maven项目&#xff08;手工制作&#xff0…

【Python】快速简单搭建HTTP服务器并公网访问「cpolar内网穿透」

转载自远程内网穿透的文章&#xff1a;【Python】快速简单搭建HTTP服务器并公网访问「cpolar内网穿透」 1.前言 Python作为热度比较高的编程语言&#xff0c;其语法简单且语句清晰&#xff0c;而且python有良好的兼容性&#xff0c;可以轻松的和其他编程语言&#xff08;(比如…