17-数据结构-查找-(顺序、折半、分块)

        简介:查找,顾名思义,是我们处理数据时常用的操作之一。大概就是我们从表格中去搜索我们想要的东西,这个表格,就是所谓的查找表(存储数据的表)。而我们怎么设计查找,才可以让计算机更快的去找到筛选我们所需要的信息呢,因此,关于怎么设计查找,就有了很多道道了。

        比如,单纯的掰着手指头去算,一个一个查,这是顺序查找;又比如,我知道了一个有序数据的最大最小的下标,我直接每次看这组数据中间的值,就跟数字爆炸一样,1和10,我猜5,猜大了,那我就从6和10中间再说他们的中间值8,这样每次可以省一半的时间,这是折半查找;再者数据特别大,我每次查找要么挨个算,要么每次省一半,所需时间还很长,这时候我们就需要分块查找了,它用的时索引结构。索引,也就相当于书的目录,我们去读一本书想读的内容,首先先去目录去找它在第几章,随后在在那一章的第一页开始往下找。分块查找就是这样的,它显示分成块,每一块的第一个下标为该块在索引表的标记,分块查找的特点就是,索引表中是有序的,但块间无序的。
        


目录

一、顺序查找

        1.1简介:

 1.2代码:

        1.3实现

二、折半查找

        2.1简介:

        2.2折半思想代码:

        2.3.折半的判断树

三、分块查找

        3.1简介


一、顺序查找

        1.1简介:

顺序查找,一般在线性表中进行查找。查找对象的存储结构适用于顺序表和链表。

线性表的顺序表中,分为有序和无序两种情况。

        哨兵思想:就是在数组的开头第一个位置,或结尾第一个位置,不存放数据,从下标1开始存放,给每次需要对比的数据,放在哨兵位置,即下标0处,与之对比。这样可以避免越界。

        无序的话,则是从头到尾挨个遍历因此时间复杂度为O(n)。

        平均查找长度:

         查找成功:\frac{n*(n+1))}{2}  \frac{1}{n} =\frac{n+1}{2},前面是查找每一个数时的查找次数的总数,是个等差数列,后面乘上每个数被查找的概率,一般都是\frac{1}{n},即平分。

        查找失败:就是给数组遍历,遍历到数据的下一位时发现找不到了,所以为n+1即可。

        有序的话,类似于二叉排序树,它可以减少查找失败时的时间,因为有序,当我找的值,遍历到比前一个大,比后一个小时,那么就查找失败了,后面不用再看了。

        平均查找长度:

          查找成功:与无序一样,\frac{n*(n+1))}{2}  \frac{1}{n} =\frac{n+1}{2}

           查找失败:(\frac{n*(n+1))}{2}+n)*\frac{1}{n+1}=\frac{n}{2}\dotplus \frac{1}{n+1},,长方形为不存在的数据范围,查找这些范围,就算失败,后面就不用找了。如图,失败总次数为:1+2+3+3,1+2+3为等差数列,后面再加个3为结尾处无穷的情况。       

 1.2代码:

这里实现了顺序表的顺序查找

主要顺序查找思想:

//查找
int SeqSearch(SSTable* s,int key)
{//哨兵处,放进需要对比的值 s->data[0]=key;int i;//随后,从表尾进行遍历对比 i=s->tabLen;//不等于key的时候就一直递减 while(s->data[i]!=key){i--;}//如果找到了,则返回i,如果没找到,即最后i=0,跟哨兵坐标相等了,则失败 return i;	
}
#include <stdio.h>
#include <string.h>
#include <malloc.h>
//顺序查找结构体
typedef struct 
{int *data; //动态一维数组 int tabLen;//表长度 }SSTable;//顺序查找表 
//初始化顺序查找表 
void InitSSTable(SSTable *s)
{printf("输入表长\n");int k;scanf("%d",&k);s->tabLen=k;s->data=(int*)malloc(sizeof(int)*s->tabLen);
}
//查找
int SeqSearch(SSTable* s,int key)
{s->data[0]=key;int i;i=s->tabLen;while(s->data[i]!=key){i--;}return i;	
}
void CreatSSTable(SSTable *s)
{printf("表长为%d\n",s->tabLen);int i=1;printf("请给数组赋值\n");while(i<s->tabLen){int x;scanf("%d",&x);s->data[i]=x;	i++;}
}  int main()
{SSTable s;InitSSTable(&s);CreatSSTable(&s);int pos;int key;printf("请输入要查找的值\n");scanf("%d",&key);pos=BinarySearch(s,key); if(pos!=0)printf("%d在表中的下标为%d\n",key,pos);elseprintf("表中没有你要找的数据\n");return 0;} 

        1.3实现

        

二、折半查找

        2.1简介:

        折半查找,又叫二分查找,它仅适用于有序的顺序表,注意两个特点:1.有序;2.顺序表,进行随机存取操作时。折半字面意思,纸每次对折一半,就跟数字爆炸一样,每次我猜数字都从范围内的中间值猜,猜大猜小,再去另一个区域去猜。

        2.2折半思想代码:

    就是对有序的一维数组,进行折半划分。先定义两个标记遍历。low和high,low在数据最左侧开始,high在数据最右侧,high和low为数组下标,因此high=n-1;数组长度减1.随后进行while循环,循环为low<=high,随后进入循环,开始,先给mid跟新值,mid=(low+high)/2,我们通过mid去看数组中mid处的值,与key对比,如果相等,则返回,如果小于key,说明找的mid偏小了,所以在右区域去找,此时更新low即可,low=mid+1;同理如果大于key,说明大了,更新high=mid-1;

//二分查找
int BinarySearch(SSTable s,int key)
{int low=0;int high=s.tabLen-1;int mid=0;while(low <= high){printf("mid=%d\n",mid);mid=(low+high)/2;if(s.data[mid]==key)return mid;else if(s.data[mid]<key){low=mid+1;	}elsehigh=mid-1;			}return 0;	
} 

        2.3.折半的判断树

   判断树,顾名思义,就是一个二叉树,通过二分法,去不断化分成两块。每个结点为mid处的值。先后顺序为,先记录low和high的初始值,当low<=high时,随后进行折半查找,先更新mid值\frac{low+high}{2},然后看数组mid处的值,与我们查找数对比,大或者小,进行high或low的更新即可。注:每次更新mid时,所得的运算结果,就是代码思想时所得结果,即3/2=1,  5/3=1,只保留整数位,

此外,做题的时候,要看好数据的下标,初始化时low永远都在数据第一个位置的下标处,high在数据最右侧。

直接上图:

树中,每个结点为数组mid下标处的数值。每次左右更新的时候,更新相应的变量。一个变一个不变。每个结点下面,写一下mid的值,方便计算下一个情况。蓝色区域为失败的区域。

三、分块查找

        3.1简介

        分块查找,仅适用于线性表顺序存储,是对顺序查找和分块查找的优化,它有两个表,一个查找表(正常存储数据的表),一个索引表(给查找表中的数据分成n块,包含该块最大值,和该块其实下标)。分块查找,索引表有序,查找表可以无序,即块内无序,块间有序。

        它用的是索引结构。索引,也就相当于书的目录,我们去读一本书想读的内容,首先先去目录去找它在第几章,随后在在那一章的第一页开始往下找。分块查找就是这样的,它显示分成块,每一块的第一个下标为该块在索引表的标记,分块查找的特点就是,索引表中是有序的,但块间无序的。

        先通过对比索引表中的值,若在在某个块之间,则通过下标,取查找表中遍历即可。

  平均查找长度:

        索引表采用折半查找,查找表采用顺序查找:折半查找相当于树,其树的高度,为平均查找长度不会超过树搞,即log(n)+1即树高的计算公式。顺序查找,则是遍历一遍。即长度为n的表通过划分为b块,每块为a个数据所以n=b*a;

所以总的平均查找为:

log(b)+1+(\frac{1}{a}*\frac{a*(a+1))}{2})

索引表采用折半查找,查找表也采用折半查找:log(b)+1+log(b)+1=log(b)+log(a)+2,其实也就是整个查找表都是有序的,直接对全部进行二分,所以为log(n)+2;

查找效率最高时:即默认n=ba时,b=a=\sqrt{n}时,索引表和查找表都时有序的,都采用二分查找,效率最高。平均查找长度最小。

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

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

相关文章

sqli-labs关卡之一(两种做法)

目录 一、布尔盲注(bool注入) 二、时间盲注(sleep注入) 一、布尔盲注(bool注入) 页面没有报错和回显信息&#xff0c;只会返回正常或者不正常的信息&#xff0c;这时候就可以用布尔盲注 布尔盲注原理是先将你查询结果的第一个字符转换为ascii码&#xff0c;再与后面的数字比较…

Redis带你深入学习数据类型set

目录 1、set 2、set相关命令 2.1、添加元素 sadd 2.2、获取元素 smembers 2.3、判断元素是否存在 sismember 2.4、获取set中元素数量 scard 2.5、删除元素spop、srem 2.6、移动元素smove 2.7、集合中相关命令&#xff1a;sinter、sinterstore、sunion、sunionstore、s…

mac电脑安装paste教程以及重新安装软件后不能使用解决方法

问题背景 mac电脑安装paste教程以及重新安装软件后不能使用解决方法。 mac电脑安装paste失败&#xff0c;安装好后还是无法使用&#xff0c;paste显示还是历史粘贴信息&#xff0c;导致无法使用。新 copy的内容也无法进入历史粘贴版里面。 笔者电脑配置信息&#xff1a;MacB…

【算法与数据结构】501、LeetCode二叉搜索树中的众数

文章目录 一、题目二、解法三、完整代码 所有的LeetCode题解索引&#xff0c;可以看这篇文章——【算法和数据结构】LeetCode题解。 一、题目 二、解法 思路分析&#xff1a;根据前面几篇文章98、LeetCode验证二叉搜索树、530、LeetCode二叉搜索树的最小绝对差。我们知道二叉搜…

Boost搜索引擎

项目背景 先说一下什么是搜索引擎,很简单,就是我们平常使用的百度,我们把自己想要所有的内容输入进去,百度给我们返回相关的内容.百度一般给我们返回哪些内容呢?这里很简单,我们先来看一下. 搜索引擎基本原理 这里我们简单的说一下我们的搜索引擎的基本原理. 我们给服务器发…

Selenium - Tracy 小笔记2

selenium本身是一个自动化测试工具。 它可以让python代码调用浏览器。并获取到浏览器中加们可以利用selenium提供的各项功能。帮助我们完成数据的抓取。它容易被网站识别到&#xff0c;所以有些网站爬不到。 它没有逻辑&#xff0c;只有相应的函数&#xff0c;直接搜索即可 …

基于SSM的精品酒销售管理系统

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;采用JSP技术开发 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#x…

Linux平台如何实现采集音视频数据并注入轻量级RTSP服务?

技术背景 好多开发者&#xff0c;问我们最多的问题是&#xff0c;为什么要设计轻量级RTSP服务&#xff1f;轻量级RTSP服务&#xff0c;和RTSP服务有什么区别&#xff1f; 针对这个问题&#xff0c;我们的回答是&#xff1a;轻量级RTSP服务解决的核心痛点是避免用户或者开发者…

MSTP + Eth-Trunk配置实验 华为实验手册

1.1 实验介绍 1.1.1 关于本实验 以太网是当今现有局域网LAN&#xff08;Local Area Network&#xff09;采用的最通用的通信协议标准&#xff0c;以太网作为一种原理简单、便于实现同时又价格低廉的局域网技术已经成为业界的主流。 本实验主要介绍了LAN网络中的Eth-Trunk技术…

Jmeter系列-Jmeter面板介绍和常用配置(2)

Jmeter面板介绍 常用菜单栏 分布式运行相关的 选项&#xff0c;可以打开日志&#xff0c;修改语言、函数助手对话框&#xff0c;还有管理插件 常用的图标 从左到右依次 新建测试计划选择测试计划模板创建一个新的测试计划打开jmeter脚本保存jmeter脚本剪切复制粘贴展开目录…

《向量数据库指南》——向量数据库和关系型数据库的区别?

向量数据库和关系型数据库是两种不同类型的数据库系统,它们在数据模型、数据存储、查询操作等方面存在许多区别。以下是向量数据库和关系型数据库的主要区别: 1、数据模型: 向量数据库:向量数据库专门设计用于存储和查询向量数据,这些数据通常表示为数值向量或嵌入向量。向…

ssm实现折线统计图

​ 方法1&#xff1a;单张数据表中的数据图表生成 图表统计&#xff0c;查看部门人数统计这里实现的时单张表中的数据实现部门人数折线统计图展示。 <script type"text/javascript">// 利用AjAx来获取后台传入的数据&#xff08;Responsebody注解传入的&…

阿里云和腾讯云2核2G服务器价格和性能对比

2核2G云服务器可以选择阿里云服务器或腾讯云服务器&#xff0c;腾讯云轻量2核2G3M带宽服务器95元一年&#xff0c;阿里云轻量2核2G3M带宽优惠价108元一年&#xff0c;不只是轻量应用服务器&#xff0c;阿里云还可以选择ECS云服务器u1&#xff0c;腾讯云也可以选择CVM标准型S5云…

springboot集成Actuator+Prometheus+Grafana

一、环境准备 PrometheusGrafana环境准备 请参考我的博文&#xff1a;https://blog.csdn.net/luckywuxn/article/details/129475991 二、代码准备 我在本次实践中使用的springboot版本是2.6.13,然后在pom.xml文件中增加一下配置 <dependency><groupId>org.sprin…

Spring安全配置: 构建安全稳固的Java应用

&#x1f337;&#x1f341; 博主猫头虎&#xff08;&#x1f405;&#x1f43e;&#xff09;带您 Go to New World✨&#x1f341; &#x1f984; 博客首页——&#x1f405;&#x1f43e;猫头虎的博客&#x1f390; &#x1f433; 《面试题大全专栏》 &#x1f995; 文章图文…

系统架构设计专业技能 ·结构化需求分析 - 数据流图

现在的一切都是为将来的梦想编织翅膀&#xff0c;让梦想在现实中展翅高飞。 Now everything is for the future of dream weaving wings, let the dream fly in reality. 点击进入系列文章目录 系统架构设计高级技能 结构化需求分析 - 数据流图 一、数据流图的基本概念二、需…

深度学习(Python)学习笔记2

第二章 感知机 2.1 感知机是什么 感知机接收多个输入信号,输出一个信号。 感知机的信号会形成流,向前方输送信息。 感知机的信号只有“流/不流”(1/0)两种取值。 本学习笔记中,0对应“不传递信号”,1对应“传递信号”。 图中、是输入信号,是输出信号,、是权重。图…

(二十五)大数据实战——kafka集群及Kafka-Eagle控制台安装与部署

前言 本节内容我们主要介绍一下搭建kafka集群以及kafka集群的一个web客户端组件Kafka-Eagle的部署安装&#xff0c;使用的kafka版本是kafka_2.12-3.0.0。在搭建kafka集群之前&#xff0c;我们要预先搭建好zookeeper集群&#xff0c;这里作者默认zookeeper的集群环境已经搭建完…

canvas基础笔记

一、简介 Canvas是HTML5中的一个元素&#xff0c;它提供了一个可以使用JavaScript绘制图形的区域。它提供了一个强大的绘图API&#xff0c;可以用于创建各种图形&#xff0c;包括线条、矩形、圆形、文本等 Canvas 是 HTML5 中的一个元素&#xff0c;用于绘制图形、动画和图像。…

el-tree 懒加载数据,展开的节点与查询条件联动

目录 效果描述实现原理步骤1&#xff1a;el-tree设置node-key步骤2&#xff1a;懒加载时对数据进行处理&#xff0c;给整个树形数据添加唯一值步骤3&#xff1a;(联动) 点击左侧树形结构&#xff0c;右侧对应查询框自动赋值步骤4&#xff1a;(联动) 右侧查询条件选择好后&#…