【数据结构】顺序查找,折半查找,分块查找的知识点总结及相应的代码实现

news2024/12/24 2:11:36

目录

1、顺序查找

定义及步骤 

代码实现

2、折半查找

定义及步骤  

代码实现

折半查找判定树 

3、分块查找

定义及步骤 


1、顺序查找

定义及步骤 

        顺序查找的定义:从数据集合的起始位置开始,逐一比较每个数据元素,直到找到所要查找的元素或者遍历完整个数据集合为止。适用于顺序表,链表,表中元素有无顺序都可以。其时间复杂度为O(n),其中n为待查找元素个数。

具体步骤如下:

  1. 从集合的第一个元素开始顺序遍历,直到找到目标元素或者遍历完整个集合。

  2. 若遍历到的元素与目标元素相同,则返回该元素的位置。

  3. 若遍历完整个集合仍未找到目标元素,则返回未找到的标识(通常为-1)。

代码实现

下面是 C 语言实现顺序查找(带哨兵)的示例代码:

#include <stdio.h>

#define MAXSIZE 100 // 定义最大容量

typedef struct {
    int data[MAXSIZE+1]; // 数据存储数组,从 data[1] 开始存储数据
    int len; // 当前长度
} SeqList;

// 初始化顺序表
void initList(SeqList *list) {
    for (int i = 1; i <= MAXSIZE; i++) {
        list->data[i] = 0;
    }
    list->len = 0;
}

// 插入元素
int insertList(SeqList *list, int elem) {
    if (list->len >= MAXSIZE) { // 判断是否已满
        return 0;
    }
    list->data[++list->len] = elem;
    return 1;
}

// 带哨兵的顺序查找
int searchList(SeqList *list, int elem) {
    int i;
    list->data[0] = elem; // 设置哨兵
    for (i = list->len; list->data[i] != elem; i--); // 从后向前遍历查找
    return i; // 返回查找到的位置
}

int main() {
    SeqList list;
    initList(&list);
    insertList(&list, 1);
    insertList(&list, 3);
    insertList(&list, 5);
    insertList(&list, 7);
    insertList(&list, 9);
    int pos = searchList(&list, 5);
    if (pos == 0) {
        printf("未找到\n");
    } else {
        printf("找到了,位置为:%d\n", pos);
    }
    return 0;
}

        在上面的代码中,我们定义了一个 SeqList 结构体来实现顺序表,其中包含了数据存储数组和当前长度。使用 initList 函数进行初始化,使用 insertList 函数插入数据。在 searchList 函数中,我们设置了一个哨兵,然后从后向前遍历查找,如果找到则返回位置,否则返回 0 表示未找到。在主函数中,我们创建了一个顺序表,插入了一些数据,然后进行查找,输出查找结果。

 

2、折半查找

定义及步骤  

        折半查找(Binary Search)又称为二分查找,是一种基于比较目标值和数组中间元素的查找算法。该算法的前提条件是数组必须已经有序。只适用于顺序表,仅适用于顺序存储结构,不适用于链式存储结构。

具体实现过程为:

1. 定义左右指针,分别指向数组的第一个元素和最后一个元素。

2. 然后取中间元素的下标,将目标值与此元素进行比较。如果目标值等于数组中间元素的值,则直接返回中间元素的下标。

3. 如果目标值小于数组中间元素的值,则将右指针移动到中间元素的左边一位。

4. 如果目标值大于数组中间元素的值,则将左指针移动到中间元素的右边一位。

5. 重复步骤2~4,直到目标值与中间元素相等或者左右指针相遇。

6. 如果左右指针相遇时,仍没有找到目标值,则表示该数组中没有目标值。

折半查找算法的时间复杂度是O(logN),相对于顺序查找的时间复杂度O(N)而言,折半查找具有更高的效率。

代码实现

下面是 C 语言实现折半查找的示例代码:

#include <stdio.h>

int binarySearch(int array[], int left, int right, int x) {
    while (left <= right) {
        int mid = left + (right - left) / 2;
        if (array[mid] == x) {
            return mid;
        }
        else if (array[mid] < x) {
            left = mid + 1;
        }
        else {
            right = mid - 1;
        }
    }
    return -1; //表示未找到
}

int main() {
    int array[] = {1, 3, 5, 7, 9, 11};
    int x = 5;
    int n = sizeof(array) / sizeof(array[0]);
    int result = binarySearch(array, 0, n - 1, x);
    if (result == -1) {
        printf("未找到该元素\n");
    }
    else {
        printf("元素在数组中的索引是:%d\n", result);
    }
    return 0;
}

        上述代码中,binarySearch函数的参数依次是数组array、数组左边界left、数组右边界right和要查找的元素x。函数通过while循环不断缩小查找范围,最终返回要查找元素在数组中的索引。在主函数中,我们定义了一个有序数组,然后调用binarySearch函数查找元素5在数组中的位置。如果返回-1,则表示未找到该元素;否则,返回元素在数组中的索引。

        注意:该算法要求在查找之前需要先对数组进行排序。因此,如果数组没有排序,需要先调用排序算法进行排序,再进行查找。

折半查找判定树 

        折半查找判定树(Binary Search Decision Tree,BSDT)是一种二叉树,用于解决折半查找(Binary Search)问题。在BSDT中,每个节点代表一个比较操作,左节点表示小于比较值,右节点表示大于比较值。叶节点代表查找成功的结果,非叶节点代表查找失败的结果。

例如,对于一个长度为7的有序数组[1, 2, 3, 4, 5, 6, 7],对应的BSDT如下图所示:

                ______4______
               /            \
          ___2___          __6__
         /       \        /     \
        1         3      5       7

        在BSDT中,从根节点(4)开始,如果要查找数字3,则先和根节点比较,由于3小于4,因此向左子节点(2)移动。然后再和2节点比较,由于3大于2,因此向右子节点(3)移动。最终到达叶节点,查找成功。

        对于长度为n的有序数组,BSDT的高度为log₂(n),因为每次比较可以剔除一半的数据,因此最多需要比较log₂(n)次。由于BSDT的高度与数据的顺序无关,因此对于任何有序数组,BSDT都可以处理。

        虽然BSDT的时间复杂度是O(log₂(n)),与折半查找一样,但是BSDT比折半查找更适合用于动态数据集合,因为BSDT可以实时更新,支持插入、删除等操作。

3、分块查找

定义及步骤 

        分块查找是一种查找算法,它是一种特殊的二分查找,用于在一组有序的数据中查找特定元素。分块查找主要用于在数据量大时,可以减少比较次数,快速查找所需的元素。

分块查找的过程分为以下几个步骤:

  1. 将数据分成若干个块:将查找的数据分割为若干块,块的大小可自行决定。每一块内的元素是有序的,块与块之间的元素大小可以不同。

  2. 对每一块内的元素建立索引:对每一块内的元素建立索引,索引可以是一个指向元素位置的指针或是一个存储最大元素值的数组。

  3. 使用二分查找在索引中查找所在块:根据查找的元素值,在索引中使用二分查找找到相应的块。

  4. 在所在块中进行线性查找:在所在块中使用线性查找查找所需元素,直到找到与之相等的元素或者超出所在块的范围为止。

  5. 返回查找结果:如果找到所需的元素,则返回该元素的位置;如果未找到,则返回不存在的信息。

        需要注意的是,分块查找的块大小和索引的大小对算法的效率有很大影响。一般来说,块的大小不要太大,索引的大小不要太小,这样才能充分利用分块查找的优势,减少查找次数,提高查找效率。

 

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

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

相关文章

百度SEO优化不稳定的原因分析(提升网站排名的稳定性)

百度SEO优化不稳定介绍蘑菇号-www.mooogu.cn SEO不稳定是指网站在搜索引擎中的排名不稳定&#xff0c;随着时间的推移会发生变化。这种情况可能会出现在网站页面结构、内容质量、外链质量等方面存在缺陷或不合理之处。因此&#xff0c;优化SEO非常重要&#xff0c;可以提高网站…

4+机器学习+实验验证

今天给同学们分享一篇4机器学习实验验证的生信文章“Identification and Analysis of Neutrophil Extracellular Trap-Related Genes in Osteoarthritis by Bioinformatics and Experimental Verification”&#xff0c;这篇文章于2023年8月31日发表在 J Inflamm Res 期刊上&am…

两个数使用JavaScript比较大小;JavaScript知识点

一、两个数使用JavaScript比较大小代码 <!DOCTYPE html> <html><head><meta charset"utf-8"><title></title></head><body><script type"text/javascript">var aprompt("请输入第一个数:"…

Web自动化测试 —— 如何进行Selenium页面数据及元素交互?啊哈

前言&#xff1a; Web自动化测试是一种常用的测试方式&#xff0c;通过在浏览器中模拟用户操作以及与页面元素的交互&#xff0c;可以有效地检验页面的功能性以及稳定性。Selenium是一款流行的Web自动化测试工具&#xff0c;在本篇文章中&#xff0c;我们将介绍如何使用Seleni…

青大数据结构【2022】

关键字&#xff1a; next数组、下三角矩阵、完全二叉树结点、静态分布动态分布、迪杰斯特拉最短路径、二叉排序树失败ASL、排序比较、二叉排序树中序遍历、链表删除最大值 一、单选 二、简答 三、应用 四、算法分析 五、算法设计

nginx反向代理vue项目

文章目录 前言一、创建站点1.添加站点2.添加ssl证书 二、反向代理vue项目1.添加反向代理2.更改vue项目配置3.修改反向代理配置 前言 项目描述&#xff1a;前端vue项目、后端Java项目、首页WordPress项目 客户要求&#xff1a;使用宝塔进行部署 需求描述&#xff1a;客户只有一…

【Java】Servlet API

Servlet API HttpServlet核心方法Servlet生命周期 HttpServletRequest核心方法 HttpServletResponse核心方法 HttpServlet 我们写 Servlet 代码的时候, 首先第一步就是先创建类, 继承自 HttpServlet, 并重写其中的某些方法. 核心方法 方法名称调用时机init在 HttpServlet 实…

李宏毅机器学习第一课

机器学习就是让机器找一个函数f&#xff0c;这个函数f是通过计算机找出来的 如果参数少的话&#xff0c;我们可以使用暴搜&#xff0c;但是如果参数特别多的话&#xff0c;我们就要使用Gradient Descent Regression (输出的是一个scalar数值) Classification &#xff08;在…

美团2024届秋招笔试第一场编程[汇总](上课口胡一下)

一.小美的好矩阵 口胡&#xff1a;模拟题&#xff0c;数据和题意灰常清楚。 俩层循环枚举每个3&#xfe61;3的小矩阵&#xff0c;然后枚举每个小矩阵&#xff0c;12个if判断俩俩相邻的字符是否相等。这里有个技巧&#xff1a;拿出中间的字符&#xff0c;这样就能使用一个偏移…

基于紫光同创FPGA的图像采集及AI加速

本原创文章由深圳市小眼睛科技有限公司创作&#xff0c;版权归本公司所有&#xff0c;如需转载&#xff0c;需授权并注明出处 适用于板卡型号&#xff1a; 紫光同创PGL50H开发平台&#xff08;盘古50K开发板&#xff09; 本篇优秀作品&#xff1a;2023集创赛全国总决赛紫光同…

Lua学习笔记:词法分析

前言 本篇在讲什么 Lua的词法分析 本篇需要什么 对Lua语法有简单认知 对C语法有简单认知 依赖Visual Studio工具 本篇的特色 具有全流程的图文教学 重实践&#xff0c;轻理论&#xff0c;快速上手 提供全流程的源码内容 ★提高阅读体验★ &#x1f449; ♠ 一级标题…

stm32之PWM呼吸灯

呼吸灯是灯从渐亮到渐灭周而复始形成的一个效果。由于51没有PWM所以需要定时器模拟PWM才能实现呼吸灯的效果&#xff0c;但是stm32的通用定时器是有PWM模式的&#xff0c;所以不需要再用软件模拟&#xff0c;精准度也高。 本实验用的基于stm32f103C8t6。在PB8引脚上接了一个le…

stm32之串口/蓝牙控制led灯

该文章记录学习stm32串口遇到的一些问题&#xff0c;完整代码地址。 一、项目描述 通过串口或蓝牙发送指令来控制led灯。 open ------> led 亮close ------> led 灭其它 -------> 反馈给串口或蓝牙错误指令 二、项目用到的模块 stm32 串口1,PA9(TX), PA10(RX)HC…

计算机组成与设计硬软件接口学习2

并行处理器&#xff1a;从客户端到云 任务级并行或进程级并行&#xff1a;通过同时运行独立的多个程序来使用多处理器 并行处理程序&#xff1a;同时在多个处理器上运行的单个程序 通过增加硬件的方式&#xff0c;将取指令和指令译码实现并行&#xff0c;一次性取出多条指令…

MQTT 协议概要

01 MQTT协议 MQTT&#xff08;消息队列遥测传输&#xff09; 是基于 TCP/IP 协议栈而构建的支持在各方之间异步通信的消息协议。MQTT在空间和时间上将消息发送者与接收者分离&#xff0c;因此可以在不可靠的网络环境中进行扩展。虽然叫做消息队列遥测传输&#xff0c;但它与消息…

[RF学习记录][ssh library][execute Command】关键字的返回值

有时候需要判断通过ssh在远程机器上执行的命令是否正常&#xff0c;使用关键字Execute Command可以在远程机器上运行命令&#xff0c;但是默认不加任何参数的话&#xff0c;没有看到范返回值&#xff0c;而这个关键字是带了几个参数的&#xff0c;简单的试验了下这几个参数&…

点云从入门到精通技术详解100篇-单期点云的高斯曲率定位桥梁潜在损伤技术研究

目录 前言 国内外研究现状 三维激光扫描对桥梁损伤检测的研究现状 基于点云高斯曲率损伤检测的研究现状 柱体偏差检测技术研究现状 存在的问题 法向量约束高斯曲率的 TLS 桥面潜在损伤区域探测 2.1 高斯曲率探伤的基本理论 2.2 点云拓扑关系建立的方法比较 2.2.1 KD-…

机器学习第十三课--主成分分析PCA

一.高维数据 除了图片、文本数据&#xff0c;我们在实际工作中也会面临更多高维的数据。比如在评分卡模型构建过程中&#xff0c;我们通常会试着衍生出很多的特征&#xff0c;最后就得到上千维、甚至上完维特征;在广告点击率预测应用中&#xff0c;拥有几个亿特征也是常见的事…

【数学建模】2023华为杯研究生数学建模F题思路详解

强对流降水临近预报 我国地域辽阔,自然条件复杂,因此灾害性天气种类繁多,地区差异大。其中,雷雨大风、冰雹、龙卷、短时强降水等强对流天气是造成经济损失、危害生命安全最严重的一类灾害性天气[1]。以2022年为例,我国强对流天气引发风雹灾害造成的死亡失踪人数和直接经济…

git:一、GIT介绍+安装+全局配置+基础操作

版本管理系统&#xff08;SVN和Git&#xff09;&#xff1a; 集中式版本控制系统&#xff08;SVN&#xff09; SVN是集中式版本控制系统&#xff0c;版本库是集中放在中央服务器的. 工作流程如下: 1.从中央服务器远程仓库下载代码 2.修改后将代码提交到中央服务器远程仓库…