二分查找与判定树

news2024/10/6 18:33:33

二分查找的算法思想

二分查找也称“折半查找”,要求查找表为采用顺序存储结构有序表。本例一律采用升序排列。二分查找每一次都会比较给定值与序列[low,high]的中间元素,该元素的下标为mid = (low+high)/2,若两者相等,则返回元素的下标为mid;如果arr[mid]>key,说明给定值key在中间元素的左边,此时只需要查找序列[low,mid-1]的中间元素;如果arr[mid]<key,说明给定值key在中间元素的右边,此时只需要查找序列[mid+1,high]。由于每一次比较arr[mid]与key失败都只需要查找剩下序列的一半,故谓之'二分查找'。显而易见,二分查找适合使用递归实现,递归的终止条件为low>high。

代码实现

注意了哈,此处的查找下标从1开始,下标0已经被弃用。

#include<iostream>
using namespace std;

int arr[10] = { 0,1,3,5,12,32,42,53,56,89};
//非递归实现
int Search_Bin(const int key) {
    //最左边的下标从1开始
    int low = 1, high = 10;
    while (low <= high) {
        int mid = (low + high) / 2;
        if (arr[mid] == key) {
            return mid;
        }
        else if (arr[mid] < key) {
            low = mid + 1;
        }
        else {
            high = mid - 1;
        }
    }
    return -1;    
}

//递归实现
int Search_Bin(const int key, int low, int high) {
    if (low > high) {
        return -1;
    }
    int mid = (low + high) / 2;
    if (arr[mid] == key)    
        return  mid;
    else if (arr[mid] > key)  
        return Search_Bin(key, low, mid - 1);
    else 
        return Search_Bin(key, mid+1, high);
}

void test01() {
    cout << "----调用非递归函数------" << endl;
    cout << "ret = 1的下标为" << Search_Bin(1) << endl;
    cout << "ret = 43的下标为" << Search_Bin(43) << endl;
    cout << "ret = 100的下标为" << Search_Bin(100) << endl;

    cout << "----调用递归函数---------" << endl;
    int len = sizeof(arr) / sizeof(int);
    cout << "ret = 1的下标为" << Search_Bin(1,1,len) << endl;
    cout << "ret = 43的下标为" << Search_Bin(43, 1, len) << endl;
    cout << "ret = 100的下标为" << Search_Bin(100, 1, len) << endl;
}

int main() {
    test01();
    return 0;
}

二分查找的判定树

二分查找的过程可以用一棵二叉树来描述,若用二叉树构造序列[low,high]的判定树,那么二叉树的根结点的存储值为序列[low,high]的中间元素的位置mid,而二叉树的左子树构造序列[low,mid-1]的判定树,右子树构造序列[mid+1,high]的判定树。查找给定值key的过程,就是逐一自上而下遍历二叉树根结点的过程。

查找次数不会超过二叉树的深度,假设序列有n个元素,那么查找的次数:count<=[log(2)n]+1。以下构造序列[1,10]的判定树,如图所示,查找的第一个下标必定为5,如果key值较arr[5]小,那么第二个查找的下标必定为2,否则为8。总而言之,倘若查找成功,查找下标的顺序就是二叉树的遍历顺序。

由于判定树的出现只是为了研究二分查找的过程,所以没有代码实现,以下借助判定树分析二分查找的时间复杂度。假设满二叉树的结点为n,j为二叉树的层次,则该层共有2^j-1个结点,由于当查找到第j层的结点时,查找也已与给定值key比较了j次。假设每一个结点被查找到的概率相同,那么每一个结点的平均查找次数为:

可见当n较大时,时间复杂度为log(2)n,相比于顺序查找提升了很多。

优缺点分析

优点:查找速度快;

缺点:

1.只适用于顺序存储结构的有序表;

2.修改与删除操作会破坏查找表的有序性,因而二分查找适合于静态查找表;

反思

二分查找的要求是,查找表为采用顺序存储结构的有序表,但现实中的有序性不只是体现在数字的比较上。有很多的排序标准是人为规定的,比如字典序,ABCD.......Z人为规定为升序排列;一个国家中的各个省市,可以根据经纬度的高低排序,或根据GDP产出排序.......总而言之,倘若一个问题适合采用二分查找,前提是适合指定解决该问题的排序规则,从而方便查找的实现。

另外,现实中的查找并不只是限制于一个值,还可以是一个范围,比如老师查找某个成绩段之间的所有学生,公司根据员工的绩效分段给员工发不同的奖金,学校要求科目成绩在[90,100]分段就可以给出A绩点等等......

以上就是我对查找学习的一些反思。

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

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

相关文章

Django的DRF从入门到精通

第一讲:建立纯净版Django项目 ① 创建Django项目 ② 创建app一个 python manage.py startapp APP名字 ③ 在settings里配置rest_framework,把不需要的全部注释掉 INSTALLED_APPS = [# django.contrib.admin,# django.contrib.auth,# django.contrib.contenttypes,# djang

centos7 安装 MySQL5.7

1.下载MySQL官方的 Yum Repository wget -i -c http://dev.mysql.com/get/mysql57-community-release-el7-10.noarch.rpm2.安装 Yum Repository yum -y install mysql57-community-release-el7-10.noarch.rpm3 使用 yum 安装 MySQL yum -y install mysql-community-server若…

推荐系统1--Deepfm学习笔记

目录 1 keras实现Deepfm demo 2 deepctr模版 3 其他实现方式 ctr_Kera 模型 数据集 预处理 执行步骤 4何为focal loss 参考 1 keras实现Deepfm 假设我们有两种 field 的特征&#xff0c;连续型和离散型&#xff0c;连续型 field 一般不做处理沿用原值&#xff0c;离散型一…

Promise学习基础学习 promise封装fs模块、AJAX请求

Promise 是什么&#xff1f; 抽象表达&#xff1a; 1、Promise 是一门新的技术&#xff08;ES6规范&#xff09; 2、Promise 是JS中进行异步编程的新解决方案 备注&#xff1a;旧方案是单纯使用回调函数 具体表达&#xff1a; 1、从语法上来说&#xff1a;Promise 是一个构造…

QML Loader(加载程序)

Loader加载器用于动态加载 QML 组件。加载程序可以加载 QML 文件&#xff08;使用 source 属性&#xff09;或组件对象&#xff08;使用 sourceComponent 属性&#xff09; 常用属性&#xff1a; active 活动asynchronous异步&#xff0c;默认为falseitem项目progress 进度so…

package.json中 版本号详解

1. 版本号简介 软件版本号有四部分组成&#xff1a; 第一部分&#xff1a;主版本号&#xff0c;当进行不兼容的 API 更改时&#xff0c;则升级主版本&#xff1b;第二部分&#xff1a;次版本号&#xff0c;当以向后兼容的方式添加功能时&#xff0c;则升级次版本&#xff1b;…

FPGA实现SDI视频编解码 SDI接收发送,提供2套工程源码和技术支持

目录1、前言2、设计思路和框架SDI接收SDI缓存写方式处理SDI缓存读方式处理SDI缓存的目的SDI发送3、工程1详解4、工程2详解5、上板调试验证并演示6、福利&#xff1a;工程代码的获取1、前言 FPGA实现SDI视频编解码目前有两种方案&#xff1a; 一是使用专用编解码芯片&#xff0…

【玩转c++】vector讲解和模拟底层实现

本期主题&#xff1a;vector的讲解和模拟实现博客主页&#xff1a;小峰同学分享小编的在Linux中学习到的知识和遇到的问题小编的能力有限&#xff0c;出现错误希望大家不吝赐vector的介绍及使用1.1vector的介绍vector其实就是一个数组的模板 &#xff0c;存放的数据可以改变而已…

不想长大,却又期待成长

长大后的世界、 会让我觉得很陌生、很陌生、 为什么我们都要长大、 为什么要学会独立&#xff1f;甚至还恨害怕长大。. 因为没有依靠、没有安全感、 虽然我知道、总有一天我要步入这个大人的世界、 可是不想、害怕、害怕自己会受伤、 世界的变化、太快了、太快了、 成人的世…

PMP项目管理项目运行环境

目录1 概述2 事业环境因素和组织过程资产3 组织系统3.1 概述3.2 组织治理框架3.2.1 治理框架3.2.2 项目治理3.3 管理要素3.4 组织结构类型3.4.1 组织结构类型3.4.2 项目管理办公室1 概述 项目所处的环境可能对项目的开展产生有利或不利的影响&#xff0c;这些影响的两大主要来…

数据结构——链表讲解(2)

作者&#xff1a;几冬雪来 时间&#xff1a;2023年3月5日 内容&#xff1a;数据结构链表讲解 目录 前言&#xff1a; 剩余的链表应用&#xff1a; 1.查找&#xff1a; 2.改写数据&#xff1a; 3.在pos之前插入数据&#xff1a; 4.pos位置删除&#xff1a; 5.在pos的后…

零死角玩转stm32初级篇1-STM32如何编译和下载程序

本篇博文目录:一.程序的编译二.程序的下载1.ISP方式2.JTAG方式3.SWD方式4.SWIM方式一.程序的编译 Keil uVision5 工具中有四个编译如图&#xff0c;他们分别表示什么意思,下面进行介绍,解释来源于<<零死角玩转stm32>>。 第一个按钮&#xff1a; Translate 就是翻译…

【项目实战】Linux下安装Nginx教程

一、环境准备 Linux版本&#xff1a;CentOS7 64位 二、具体步骤 2.1 步骤1&#xff1a;确认系统中安装以下基础依赖 确认系统中安装了gcc、pcre-devel、zlib-devel、openssl-devel。 在安装Nginx前首先要确认系统中安装了gcc、pcre-devel、zlib-devel、openssl-devel。 yu…

Feature interation—— Bridge、Fusion、Filte

Feature interation&#xff08;特征交互&#xff09;&#xff1a;物品不同模态的表示属于不同的语义空间&#xff0c;并且每个用户对模态也有不同的偏好。因此&#xff0c;多模态推荐系统&#xff08;MRS&#xff09;寻求融合和交互多模态特征来生成用户和物品的特征表示。特征…

STM32开发(六)STM32F103 通信 —— RS485 Modbus通信编程详解

文章目录一、基础知识点二、开发环境三、STM32CubeMX相关配置1、STM32CubeMX基本配置2、STM32CubeMX RS485 相关配置四、Vscode代码讲解五、结果演示以及报文解析一、基础知识点 了解 RS485 Modbus协议技术 。本实验是基于STM32F103开发 实现 通过RS-485实现modbus协议。 准备…

DJ1-1 计算机网络和因特网

目录 一、计算机网络 二、Interent 1. Internet 的介绍 2. Internet 的具体构成 3. Internet 提供的服务 4. Internet 的通信控制 一、计算机网络 定义&#xff1a;是指两台以上具有独立操作系统的计算机通过某些介质连接成的相互共享软硬件资源的集合体。 计算机网络向…

Python机器学习17——极限学习机(ELM)

本系列基本不讲数学原理&#xff0c;只从代码角度去让读者们利用最简洁的Python代码实现机器学习方法。 背景&#xff1a; 极限学习机(ELM)也是学术界常用的一种机器学习算法&#xff0c;严格来说它应该属于神经网络&#xff0c;应该属于深度学习栏目&#xff0c;但是我这里把它…

C/C++开发,无可避免的多线程(篇四).线程与函数的奇妙碰撞

一、函数、函数指针及函数对象 1.1 函数 函数&#xff08;function&#xff09;是把一个语句序列&#xff08;函数体, function body&#xff09;关联到一个名字和零或更多个函数形参&#xff08;function parameter&#xff09;的列表的 C 实体&#xff0c;可以通过返回或者抛…

MongoDB分片教程

一、概述分片是一种将数据分布在多个 机器。MongoDB使用分片来支持具有非常大数据的部署 集和高吞吐量操作。具有大型数据集或高吞吐量应用程序的数据库系统可以 挑战单个服务器的容量。例如&#xff0c;高查询率可以 耗尽服务器的 CPU 容量。工作集大小大于 系统的 RAM 会给磁…

初学者的第一个Linux驱动

软件环境&#xff1a;Ubuntu20.04 Linux内核源码&#xff1a;3.4.39 硬件环境&#xff1a;GEC6818 什么是驱动&#xff1f;简单来说就是让硬件工作起来的程序代码。 Linux驱动模块加载有两种方式&#xff1a; 1、把写好的驱动代码直接编译进内核。 2、把写好的驱动代码编…