顺序查找和折半查找

顺序查找:

对于无序的情况:

什么是顺序查找:顺序查找的实现方式(存储),是含有两种的方式进行存储的,一种是顺序表的形式进行存储,还有一种是使用链表的形式进行存储的。采用顺序查找的方式是含有也是含有两种查找方式的:一个是从从头到尾进行查找,一种是从尾到头进行查找的!两种的效率都是差不多的,时间复杂度基本上是一致的。

两种代码实现的方式:

从头到尾:

//从头到尾的方式进行代码的查找实现
public static void sortHead(int [] arr , int key){int i;//左边的for (i = 0; i < arr.length  ; i++){if(arr[i] == key) {break;}};System.out.println(i);
}

直接进行时间复杂度的计算的判断:

查找成功的时间复杂度为:

查找成功

$$
Pi*(n - i + 1)求和
$$

查找失败

$$
n+1
$$

从尾到头来进行查找操作

//从尾的情况来进行相应的查找的操作
public static void tailSort(int [] arr , int key){int j;for (j = arr.length - 1; j >= 0 ; j--) {if(arr[j] == key){break;}}System.out.println(j);
}

比较一下两者的查找效率,总体上来看得话,这两个的效率数量级是一致的。

这种的查找的时间效率非常的低,在数组的长度非常大的情况要进行对整个数组进行遍历操作,耗时的!这种是最简单的,没有对数组当中的元素含有任何的限制的,毫无顺序可言。但是对于单链表的形式进行存储的话,就只能使用这种方式一个一个进行的遍历操作。

对于有序的情况:

给定一个有序的数组,当想要对这个数组当中的元素进行查找情况(由小到大的顺序进行存储的)。

当查找的元素arr[i] 的位置的元素大小小于key的值,但是arr[i+1]的位置大小是大于key的值的。这说明整个这个数组当中都没有一个等于key的元素的,可以直接进行退出遍历操作了。

对于这种的有序的数组进行查找,含有n+1个不符合查找的情况的区间。当key的值落到了这个区间的话,就可以直接进行退出循环遍历操作了。

public static void getSort(int [] arr , int key){Arrays.sort(arr);int i;for( i = 0 ; i < arr.length; i++){if(arr[i] == key){System.out.println(i);break;}//数组越界i+1else if(i < arr.length - 1 && arr[i] < key && arr[i + 1] > key){System.out.println("找不到一个合适的");break;}}if(i == arr.length){System.out.println("找不到元素");}
}

上面是采用的是顺序查找的方式进行实现的。

有没有更好的方式来将代码进行更加妙实现的呢?

折半查找:

对一个有序的数组可以进行有序的查找操作,具体的实现流程是怎么样的?

给定一个数组(有序的),使用两个指针的[low , high],分别指向第一个位置的元素和最后一个位置的元素。然后不断的取这两个位置的中间值(mid),根据中间值的位置来进行判断操作[是将high移动(mid - 1),还是将low移动(mid + 1)].

以流程图的形式来将其进行展示!

代码实现:

package search;/*** @program: 数据结构* @description        二分查找* 二分查找是对有序的一串数组进行查找一个给定的数,若查找不到的话就返回一个查找不到的信息。* @author: YangTao* @create: 2023-07-28 10:34**/
public class BinarySearch {public static void main(String[] args) {int [] arr = new int[10];arr[0] = 1;for (int i = 1; i < arr.length; i++) {arr[i] = arr[i - 1] * 2;}for (int i = 0; i < arr.length; i++) {System.out.println(arr[i]);}
//        进行数据查找int number =  16;int left = 0;int right = arr.length - 1;int middle = 0;int index = -1;while(left <= right){middle = (left + right)/2;if(arr[middle] == number){index = middle;break;}if(arr[middle] < number){left++;}if(arr[middle] > number){right--;}}System.out.println("查找数得索引为:" + index);}
}

得到的节点连接的情况(判定树):

这样的判定树可以清晰的展示结果:处于哪一层就得要进行比较多少次!

得到的情况就是:

查找成功----

$$
(1+2*2+3*4+4*4)/ 11
$$

查找失败----

$$
(4 * 4 + 8 * 5)/ 12
$$

通过公式将整个的时间复杂度都求出来的情况:

查找成功的情况:

$$
1/n[1 + 2 * 2 + 3 * 4 + 4 * 8 + h * 2^(h - 1)]
$$

$$
((1 + n)/n) * log2(n + 1) - 1
$$

$$
log2(n + 1) - 1
$$

在处理mid的时候会出现两种情况:当使用的是向下取整的情况,在比较左右子树的大小的情况,左子树节点的个数可能是等于右子树的节点个数或者是为右子树节点个数减去1的情况。

但使用的是向上取整就会出现相反的情况:

右子树节点的个数可能是等于左子树的节点个数或者是为左子树节点个数减去1的情况。

这种查找的形式的二叉树二会是一个平衡二叉树。左右子树的高度差的不会超过1。

分块查找:

为数组建立一个索引表,并将数组分割成为若干个块,索引表中一次存放每个块内的最大值和块内元素的存储区间(块内无序,块间有序)

分块查找的过程:

  • 在索引表中确定key所属的分块(索引表可以采用顺序查找,也可以采用折半查找)

  • 在块内查找(非有序,只能顺序查找)

3.2.分块查找手算过程

3.2.1.顺序查找索引表

以查找36为例

  • 在索引表中依次遍历找到第一个大于它的值,即40

  • 移动到40指向的数组区间的第一个元素,即数组下标9

  • 从数组下标9开始遍历,40→36 找到36

以查找17为例

  • 在索引表中依次遍历找到第一个大于它的值,即20

  • 移动到20指向的数组区间的第一个元素,即数组下标2

  • 从数组下标2开始遍历,13→19→16→20

  • 此时移动到20,数组下标为5,到索引表中17的最后一个元素,仍匹配失败,说明表中没有17

3.2.2.折半查找索引表

索引表只是保存元素的数组区间,方便在数组中寻找元素(相对位置),就算在索引表上找到相应元素,还是得再去数组中重新再找一次

以查找30为例

  • low指向10,high指向50,mid = (low + high) / 2 指向 2,即指向30

  • 到30所指向的数组区间依次查找

以查找19为例

  • low指向10,high指向50→mid指向30,mid > key , high = mid - 1

  • low指向10,high指向20→mid指向10,mid < key, low = mid + 1

  • low指向20,high指向20→mid指向20,mid > key, high = mid - 1

  • low指向20,high指向10→low > high 折半查找结束

  • 到low所指向的元素区间进行逐一遍历查找

去low指向区间查找的原因:最后low的左边一定小于key,而分块查找的索引表存放的是每块的最大值

除了能在key能在索引表上直接找到,否则都要执行到low > high,才能确定key元素所可能存在的数组区间范围

代码实现分块查找:

找到每一个块当中的最大的元素,同时记录每一个块的起始位置和结束位置。

package search;import java.util.Scanner;/*** @program: 数据结构* @description* @author: YangTao* @create: 2024-04-23 16:54**/
public class BlockSearch {public static void main(String[] args) {int [] arr = {9 , 22 , 12 , 14 , 35 , 42 , 44 , 38 , 48 , 60 , 58 , 47 , 78 , 80 , 77 , 82};//block的key的大小是属于逐渐递增的Block [] blocks = {new Block(22 , 0 , 3) , new Block(44 , 4 , 7) , new Block(60 , 8 , 11) , new Block(82 , 12 , 15)};System.out.println("输入查找的元素");Scanner scanner = new Scanner(System.in);int key = scanner.nextInt();//进行查找int index = search(blocks, arr, key);if(index == -1){System.out.println("没有找到");}elseSystem.out.println("key位于的位置是" + index);}public static int search(Block [] blocks , int [] arr , int key ){//对blocks的数组进行二分查找//当找到的元素是为key的话就可以直接获得这个位置的block的起始位置和结束位置。int low = 0;int high = blocks.length - 1;int mid = -1;int indexBlock = -1;while(low <= high){mid = (low + high) / 2;//找到了if(blocks[mid].key == key){//进行返回indexBlock = mid;break;}else if(blocks[mid].key > key){high = mid - 1;}else {low = mid + 1;}}//没有在主的索引位置找到相应的key值if(indexBlock == -1){indexBlock = low;}int index = -1;//在分块当中继续进行查找操作for(int i = blocks[indexBlock].low ; i <= blocks[indexBlock].high ; i++){if(arr[i] == key){index = i;break;}}return index;}
}//定义一个存储索引块表的类:
class Block{int key;        //最大的节点的元素在块当中int low;int high;public Block(int key, int low, int high) {this.key = key;this.low = low;this.high = high;}
}

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

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

相关文章

架构师系列- 消息中间件(15)-kafka业务实战

7.1 顺序性场景 7.1.1 场景概述 假设我们要传输一批订单到另一个系统&#xff0c;那么订单对应状态的演变是有顺序性要求的。 已下单 → 已支付 → 已确认 不允许错乱&#xff01; 7.1.2 顺序级别 1&#xff09;全局有序&#xff1a; 串行化。每条经过kafka的消息必须严格…

ElasticSearch教程入门到精通——第二部分(基于ELK技术栈elasticsearch 7.x+8.x新特性)

ElasticSearch教程入门到精通——第二部分&#xff08;基于ELK技术栈elasticsearch 7.x8.x新特性&#xff09; 1. JavaAPI-环境准备1.1 新建Maven工程——添加依赖1.2 HelloElasticsearch 2. 索引2.1 索引——创建2.2 索引——查询2.3 索引——删除 3. 文档3.1 文档——重构3.2…

react,Chart

一、基础图&#xff1a;https://ant-design-charts.antgroup.com/ Ant Design Charts 1. 首先要下载ant-design/charts&#xff0c;然后在页面中添加如下柱状图代码: import React from react; import { Column } from ant-design/chartsconst DemoColumn: React.FC () …

百度智能云千帆 ModelBuilder 技术实践系列:通过 SDK 快速构建并发布垂域模型

​百度智能云千帆大模型平台&#xff08;百度智能云千帆大模型平台 ModelBuilder&#xff09;作为面向企业开发者的一站式大模型开发平台&#xff0c;自上线以来受到了广大开发者、企业的关注。至今已经上线收纳了超过 70 种预置模型服务&#xff0c;用户可以快速的调用&#x…

深入理解冯诺依曼体系结构

文章目录 冯诺依曼体系结构概念冯诺依曼体系结构的优势冯诺依曼体系结构的现实体现 冯诺依曼体系结构概念 冯诺依曼体系结构也称普林斯顿结构&#xff0c;是现代计算机发展的基础。它的主要特点是“程序存储&#xff0c;共享数据&#xff0c;顺序执行”&#xff0c;即程序指令和…

代码随想录算法训练营Day10 | 232.用栈实现队列、225. 用队列实现栈

232.用栈实现队列 题目&#xff1a;请你仅使用两个栈实现先入先出队列。队列应当支持一般队列支持的所有操作&#xff08;push、pop、peek、empty&#xff09;&#xff1a; 实现 MyQueue 类&#xff1a; void push(int x) 将元素 x 推到队列的末尾int pop() 从队列的开头移除…

【leetcode面试经典150题】75. 二叉树展开为链表(C++)

【leetcode面试经典150题】专栏系列将为准备暑期实习生以及秋招的同学们提高在面试时的经典面试算法题的思路和想法。本专栏将以一题多解和精简算法思路为主&#xff0c;题解使用C语言。&#xff08;若有使用其他语言的同学也可了解题解思路&#xff0c;本质上语法内容一致&…

修改Docker容器内文件的三种方式

说明&#xff1a;本文介绍修改Docker容器内文件的三种方式 方式一&#xff1a;直接修改 敲下面的命令&#xff0c;进入Docker容器&#xff0c;如mysql docker exec -it mysql /bin/bash修改mysql的配置文件&#xff0c;/etc/my.cnf vim /etc/my.cnf如下&#xff0c;如果vim…

【Hadoop】-Apache Hive使用语法与概念原理[15]

一、数据库操作 创建数据库 create database if not exists myhive; 使用数据库 use myhive; 查看数据库详细信息 desc database myhive; 数据库本质上就是在HDFS之上的文件夹。 默认数据库的存放路径是HDFS的&#xff1a;/user/hive/warehouse内 创建数据库并指定hdfs…

attempt to compare nil with number -- 黑马点评出现问题

问题情况 : 主要问题 : 调用lua执行redis时&#xff0c;有一个值会接受nil&#xff08;因为redis中没有该数据&#xff09;或者数值&#xff0c;当该值为nil时执行报错&#xff0c;因为会用到将该值与其他数字比较&#xff0c;故报错attempt to compare nil with number 当然…

生成完美口型同步的 AI 代言人视频(及其实现原理详解)

目录 什么是Heygen? Heygen注册 Video Translation&#xff08;视频翻译 完美口型同步&#xff09; 实现原理详解 视频翻译部分 完美口型同步部分 什么是Heygen? Heygen是一款在线工具&#xff0c;可帮助您生成具有完美口型同步的 AI 代言人视频。 Heygen注册 https:…

关于springboot内置tomcat最大请求数配置的一些问题

前言 springboot内置了tomcat。那么一个springboot web应用&#xff0c;最大的请求链接数是多少呢&#xff1f;很早以前就知道这个是有个配置&#xff0c;需要的时候&#xff0c;百度一下即可。但&#xff0c;事实并非如此&#xff0c;有几个问题我想大多数人还真不知道。比如…

前端学习<四>JavaScript——54-原型链

常见概念 构造函数 构造函数-扩展 原型规则和示例 原型链 instanceof 构造函数 任何一个函数都可以被 new&#xff0c;new 了之后&#xff0c;就成了构造方法。 如下&#xff1a; function Foo(name, age) {this.name name;this.age age;//retrun this; //默认有这…

大型语言模型高效推理综述

论文地址&#xff1a;2404.14294.pdf (arxiv.org) 大型语言模型&#xff08;LLMs&#xff09;由于在各种任务中的卓越表现而受到广泛关注。然而&#xff0c;LLM推理的大量计算和内存需求给资源受限的部署场景带来了挑战。该领域的努力已经朝着开发旨在提高LLM推理效率的技术方…

C语言递归刷题(一)

目录 走台阶题目思路代码 西格玛题目思路代码 用函数实现数的阶乘题目思路代码 digit题目思路代码 Hermite多项式题目思路代码 排列数题目思路代码 逆序输出题目思路代码 结语 走台阶 题目 描述 小乐乐上课需要走n阶台阶&#xff0c;因为他腿比较长&#xff0c;所以每次可以选…

挑战特斯拉?深蓝汽车与华为强强联手

作为中国乃至全球汽车行业的盛宴&#xff0c;4月25日在中国国家展览中心揭幕的2024北京国际车展&#xff0c;吸引了无数企业行业人士的关注。 而就在车展开幕当天&#xff0c;深蓝汽车发布会就爆出了一个大新闻&#xff1a;深蓝汽车将携手华为&#xff0c;打造比特斯拉更好的智…

【开发问题记录】启动某个服务时请求失败(docker-componse创建容器时IP参数不正确)

问题记录 一、问题描述1.1 产生原因1.2 产生问题 二、问题解决2.1 找到自己的docker-compose.yml文件2.2 重新编辑docker-compose.yml文件2.3 通过docker-componse重新运行docker-compose.yml文件2.4 重新启动docker容器2.5 查看seata信息 一、问题描述 1.1 产生原因 因为我是…

FPGA 以太网通信UDP通信环回

1 实验任务 上位机通过网口调试助手发送数据给 FPGA &#xff0c; FPGA 通过 PL 端以太网接口接收数据并将接收到的数据发送给上位机&#xff0c;完成以太网 UDP 数据的环回。 2 系统设计 系统时钟经过PLL时钟模块后&#xff0c;生成了两种不同频率和相位的时钟信号&#…

Python 面向对象——6.封装

本章学习链接如下&#xff1a; Python 面向对象——1.基本概念 Python 面向对象——2.类与对象实例属性补充解释&#xff0c;self的作用等 Python 面向对象——3.实例方法&#xff0c;类方法与静态方法 Python 面向对象——4.继承 Python 面向对象——5.多态 1. 封装的基…

unity cinemachine相机 (案例 跟随角色移动)

安装相机包 打开包管理工具 在 unity registry 搜索cinemachine 会在maincamera中生成一个组件cinemachineBrain 只能通过虚拟相机操控 主相机 虚拟相机的参数 案例 1.固定相机效果 位置 在固定的地方 默认的模式 2.相机跟随人物效果 焦距设置 20 跟随设置 把playere…