线性表的查找

2023-11-04

1、顺序查找

(1)顺序查找介绍

顺序查找的查找过程为:从表的一端开始,依次将记录的关键字和给定的值进行比较,若某个记录的关键字和给定的值是一样的,则查找成功;反之,若扫描整个表之后,任然没有找到关键字和给定的值相等的记录,则查找失败!
适用用线性表和链表!

(2)、代码实现

(1)、顺序查找

//顺序查找 
int Search_Seq(SSTable S,int key){
	for (int i = S.length - 1; i >= 1 ; i-- )   //i = S.length - 1,S.data[S.length - 1] = -1结束标志符
	{
		if (S.data[i] == key)
		    return i;                           //从前往后查找成功! 
	}
	return 0;                                   //查找失败 
}

但是上面的算法中每一步都要检查整个表是否查找完毕,即每次循环都要判断循环变量 i >= 1 的检测。下面设置哨监视的查找算法就是对这种情况的改进!

(2)、设置哨监视的顺序查找

哨监视的顺序查找是将查找值 key 放在S.data[0]中,然后执行操作!

//哨监视的顺序查找
int Search_Seq1(SSTable S,int key){
	//从后往前找直到 i = 0,此时是查找失败;否则会返回 1 ~  S.length - 1 之间的位置数 
	int i; 
	S.data[0] = key; 
	for ( i = S.length - 1; S.data[i] != key ; i-- );
	return i; 
}

这个算法当S.length >= 1000的时候,进行查找的实际几乎会减少一半

(3)、所有代码如下

#include<string.h>
#include<stdio.h>
#define MaxSize 20
#include<iostream>
#include<stdlib.h>
#define endl '\n'
using namespace std; 
typedef struct{
	int *data;
	int length; 
}SSTable;

void InputElement(SSTable &S){
	S.data = (int *) malloc (sizeof(int)*MaxSize);
	S.length = 1;
	cout<<"\n请输入要排序的数!结束请输入 -1 :"; 
	for (int i = 1 ; i < MaxSize && S.data[i-1] != -1; i++){   //将S.data[0]闲置不用 
		cin>> S.data[i];
		S.length++;
	} 
	int i = 1;
	cout<<"\n输入如下:";
	while(S.data[i] != -1){
		cout<<S.data[i]<<" "; 
		i ++;
	}
} 

//顺序查找 
int Search_Seq(SSTable S,int key){
	for (int i = S.length - 1; i >= 1 ; i-- )   //i = S.length - 1,S.data[S.length - 1] = -1结束标志符
	{
		if (S.data[i] == key)
		    return i;                           //从前往后查找成功! 
	}
	return 0;                                  //查找失败 
}

//哨监视的顺序查找
int Search_Seq1(SSTable S,int key){
	//从后往前找直到 i = 0,此时是查找失败;否则会返回 1 ~  S.length - 1 之间的位置数 
	int i; 
	S.data[0] = key; 
	for ( i = S.length - 1; S.data[i] != key ; i-- );
	return i; 
}

main(){
	SSTable S;
	InputElement(S);
	cout<<"\n\n请输入查找关键字:"; 
	int key; 
	cin>>key;
	if (Search_Seq(S,key))
	    cout<<"\n查找成功!在顺序表中是第 "<<Search_Seq(S,key)<<" 个元素!\n";
	else
	    cout<<"\n查找失败!\n";
	cout<<"\n-----------------------------------------前后对比如下-----------------------------------------------------\n"; 
	if (Search_Seq1(S,key))
	    cout<<"\n查找成功!在顺序表中是第 "<<Search_Seq1(S,key)<<" 个元素!\n";
	else
	    cout<<"\n查找失败!\n";
} 

(4)、结果测试

在这里插入图片描述
在这里插入图片描述

(3)、算法分析

顺序查找的优点是:算法简单,对表结构没有任何的要求,既适用于顺序结构,同时又适用于链式结构,无论记录按关键字是否有序均可应用!但是其平均查找长度ASL比较大,ASL = 1/n * (1 + 2 + 3 + …+ n) = (n + 1)/2,所以其查找效率很低。当查找个数n很大的时候,不适合采用顺序表!

2、折半查找(二分查找)

(1)、二分查找介绍

折半查找是一种效率较高的查找方法,但是折半查找要求线性表必须采用顺序存储结构,因为顺序表拥有比随机存取访问的特性,而链表没有,故不能使用链表实现二分查找!并且表中的元素必须有序,要么升序要么降序,如果不是则无法使用实现对比折半查找(下面的代码实现中假定是升序)
从表的中间记录开始,如果查找的值和中间记录的值相等,则查找成功;如果查找值和大于或者小于中间记录的关键字,则在表中大于或小于中间记录的那一半中查找,这样重复操作,直到查找成功!或者在某一步中查找区间为空,则代表查找失败!

(2)、代码实现

#include<string.h>
#include<stdio.h>
#define MaxSize 20
#include<iostream>
#include<stdlib.h>
#define endl '\n'
using namespace std; 
typedef struct{
	int *data;
	int length; 
}SSTable;

//输入数 
void InputElement(SSTable &S){
	S.data = (int *) malloc (sizeof(int)*MaxSize);
	S.length = 1;
	cout<<"\n请输入要排序的数!结束请输入 -1 :"; 
	for (int i = 0 ; i < MaxSize && S.data[i-1] != -1; i++){   
		cin>> S.data[i];
		S.length++;
	} 
	int i = 0;
	cout<<"\n输入如下:";
	while(S.data[i] != -1){
		cout<<S.data[i]<<" "; 
		i ++;
	}
} 

int Search_Bin(SSTable S,int key){
	int low = 0, high = S.length -1,mid;
	while(low <= high){                 //查找成功的情况 
		mid = (low + high)/2;
		if (S.data[mid] == key) 
		    return mid;
		else if(S.data[mid] > key)
		    high = mid - 1;
		else 
		    low = mid + 1; 
	} 
	return 0;                           //查找失败,即low > high 
}

main(){
	SSTable S;
	InputElement(S);
	cout<<"\n\n请输入查找关键字:"; 
	int key; 
	cin>>key;
	if (Search_Bin(S,key))
	    cout<<"\n查找成功!在顺序表中是第 "<<Search_Bin(S,key)+1<<" 个元素!\n";
	else
	    cout<<"\n查找失败!\n";
} 

在这里插入图片描述
当 low = high的时候,查找区间还有最后一个元素需要执行判断操作!

(3)、算法分析

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
所以折半查找可以使用二叉树来描述!由此可见,折半查找在查找成功的时候进行比较的关键字个数一定不超过树的深度!而判定树的形态只与表记录的个数 n 有关,而与关键字的取值无关!在第五章我们知道,具有n个节点的二叉树的高为 h = 【log 2 n】+ 1(向下取整);或h = 【log 2 (n+1)】向上取整。因此折半查找在查找成功的时候和给定值进行比较的关键字个数至多不超过 树高h
判定树的关键字:左 < 中 < 右,满足 二叉排序树 的定义,失败节点为 n + 1个,是成功节点空链域的个数,所以查找失败的时候和给定值进行比较的关键字个数最多也超过 树高h
所以折半查找的时间复杂度是O(log 2 n)!
折半查找的优点是:查找次数少,查找效率高,但是必须是有序的顺序表,而不是链表!并且,查找前必须排序!同时为了保持顺序表的有序性,对表进行插入或者删除的时候,平均要比较移动表中一半的元素。因此,折半查找不适合使用于数据元素经常变动的线性表!

(4)、平均查找长度

ASL = (n+1)/n * log2 (n + 1)- 1 当n较大的时候可以直接取为ASL = log2 (n + 1)- 1

3、分块查找(索引顺序查找)

(1)、分块查找介绍

是一种性能介于顺序查找和折半查找之间的一种查找方法!
分块查找的基本思想:
将查找表分为若干子块。块内的元素可以无序,但块之间是有序的,即第一个块中的最大关键字小于第二个块中的所有记录的关键字,第二个块中的最大关键字小于第三个块中的所有记录的关键字,以此类推。再建立一个索引表,索引表中的每个元素含有各块的最大关键字和各块中的第一个元素的地址,索引表按关键字有序排列(王道中是每个元素含有各块的最大关键字和各块中的第一个元素的地址和最后一个元素的地址)
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

(2)、分块查找的过程

● 第一步是在索引表中确定待查记录所在的块,可以顺序查找或折半查找索引表。
● 第二步是在块内顺序查找。

(3)、使用折半查找索引表

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

(4)、ASL分析

******、索引查找采用顺序查找的ASL分析

在这里插入图片描述

当 s 取根号n的时候,ASLmin = 根号n + 1,这个值比顺序查找有了很大的改进,但是远不及折半查找!

******、索引查找采用折半查找的ASL分析

在这里插入图片描述

但是严蔚敏版数据结构与算法中 ASL = log2[n/s + 1] + s/2 = log2[b + 1] + s/2,和王道中有些不同!

(5)、算法分析

在表中插入或者删除数据的时候,只要找到该元素对应的块,就可以在该块内进行插入或者删除操作。由于块内是无序的,故插入或者删除比较容易,无需进行大量的移动。如果线性表既要实现快速查找又要经常插入或者删除的动态变化,则可以使用分块查找,因为块间可以使用折半查找(二分查找),而块内无序可以实现插入或者删除,不需要大量的移动!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

线性表的查找 的相关文章

  • 如何使用 C# 中的参数将用户重定向到 paypal

    如果我有像下面这样的简单表格 我可以用它来将用户重定向到 PayPal 以完成付款
  • WCF RIA 服务 - 加载多个实体

    我正在寻找一种模式来解决以下问题 我认为这很常见 我正在使用 WCF RIA 服务在初始加载时将多个实体返回给客户端 我希望两个实体异步加载 以免锁定 UI 并且我想利用 RIA 服务来执行此操作 我的解决方案如下 似乎有效 这种方法会遇到
  • GLKit的GLKMatrix“列专业”如何?

    前提A 当谈论线性存储器中的 列主 矩阵时 列被一个接一个地指定 使得存储器中的前 4 个条目对应于矩阵中的第一列 另一方面 行主 矩阵被理解为依次指定行 以便内存中的前 4 个条目指定矩阵的第一行 A GLKMatrix4看起来像这样 u
  • ASP.NET MVC:这个业务逻辑应该放在哪里?

    我正在开发我的第一个真正的 MVC 应用程序 并尝试遵循一般的 OOP 最佳实践 我正在将控制器中的一些简单业务逻辑重构到我的域模型中 我最近一直在阅读一些内容 很明显我应该将逻辑放在域模型实体类中的某个位置 以避免出现 贫血域模型 反模式
  • 从Web API同步调用外部api

    我需要从我的 Web API 2 控制器调用外部 api 类似于此处的要求 使用 HttpClient 从 Web API 操作调用外部 HTTP 服务 https stackoverflow com questions 13222998
  • C# 中通过 Process.Kill() 终止的进程的退出代码

    如果在我的 C 应用程序中 我正在创建一个可以正常终止或开始行为异常的子进程 在这种情况下 我通过调用 Process Kill 来终止它 但是 我想知道该进程是否已退出通常情况下 我知道我可以获得终止进程的错误代码 但是正常的退出代码是什
  • 使用 WebClient 时出现 System.Net.WebException:无法创建 SSL/TLS 安全通道

    当我执行以下代码时 System Net ServicePointManager ServerCertificateValidationCallback sender certificate chain errors gt return t
  • 带动态元素的 WPF 启动屏幕。如何?

    我是 WPF 新手 我需要一些帮助 我有一个加载缓慢的 WPF 应用程序 因此我显示启动屏幕作为权宜之计 但是 我希望能够在每次运行时更改屏幕 并在文本区域中显示不同的引言 这是一个生产力应用程序 所以我将使用非愚蠢但激励性的引言 当然 如
  • 显示UnityWebRequest的进度

    我正在尝试使用下载 assetbundle统一网络请求 https docs unity3d com ScriptReference Networking UnityWebRequest GetAssetBundle html并显示进度 根
  • 如何在整个 ASP .NET MVC 应用程序中需要授权

    我创建的应用程序中 除了启用登录的操作之外的每个操作都应该超出未登录用户的限制 我应该添加 Authorize 每个班级标题前的注释 像这儿 namespace WebApplication2 Controllers Authorize p
  • 什么时候虚拟继承是一个好的设计? [复制]

    这个问题在这里已经有答案了 EDIT3 请务必在回答之前清楚地了解我要问的内容 有 EDIT2 和很多评论 有 或曾经 有很多答案清楚地表明了对问题的误解 我知道这也是我的错 对此感到抱歉 嗨 我查看了有关虚拟继承的问题 class B p
  • 如何使用 C# / .Net 将文件列表从 AWS S3 下载到我的设备?

    我希望下载存储在 S3 中的多个图像 但目前如果我只能下载一个就足够了 我有对象路径的信息 当我运行以下代码时 出现此错误 遇到错误 消息 读取对象时 访问被拒绝 我首先做一个亚马逊S3客户端基于我的密钥和访问配置的对象连接到服务器 然后创
  • 如何从两个不同的项目中获取文件夹的相对路径

    我有两个项目和一个共享库 用于从此文件夹加载图像 C MainProject Project1 Images 项目1的文件夹 C MainProject Project1 Files Bin x86 Debug 其中有project1 ex
  • 通过指向其基址的指针删除 POD 对象是否安全?

    事实上 我正在考虑那些微不足道的可破坏物体 而不仅仅是POD http en wikipedia org wiki Plain old data structure 我不确定 POD 是否可以有基类 当我读到这个解释时is triviall
  • 如何将带有 IP 地址的连接字符串放入 web.config 文件中?

    我们当前在 web config 文件中使用以下连接字符串 add name DBConnectionString connectionString Data Source ourServer Initial Catalog ourDB P
  • C# 成员变量继承

    我对 C 有点陌生 但我在编程方面有相当广泛的背景 我想做的事情 为游戏定义不同的 MapTiles 我已经像这样定义了 MapTile 基类 public class MapTile public Texture2D texture pu
  • 混合 ExecutionContext.SuppressFlow 和任务时 AsyncLocal.Value 出现意外值

    在应用程序中 由于 AsyncLocal 的错误 意外值 我遇到了奇怪的行为 尽管我抑制了执行上下文的流程 但 AsyncLocal Value 属性有时不会在新生成的任务的执行范围内重置 下面我创建了一个最小的可重现示例来演示该问题 pr
  • C# 模拟VolumeMute按下

    我得到以下代码来模拟音量静音按键 DllImport coredll dll SetLastError true static extern void keybd event byte bVk byte bScan int dwFlags
  • C++ 标准是否指定了编译器的 STL 实现细节?

    在写答案时this https stackoverflow com questions 30909296 can you put a pimpl class inside a vector我遇到了一个有趣的情况 这个问题演示了这样一种情况
  • 对来自流读取器的过滤数据执行小计

    编辑问题未得到解答 我有一个基于 1 个标准的过滤输出 前 3 个数字是 110 210 或 310 给出 3 个不同的组 从流阅读器控制台 问题已编辑 因为第一个答案是我给出的具体示例的字面解决方案 我使用的实际字符串长度为 450 个

随机推荐

  • NoSQL数据库概述

    简介 本文首先解释了NoSQL的出现的原因 介绍了NoSQL数据库所依据的理论和原则 然后分别介绍了四种NoSQL数据库的类型 以及其代表产品 并讨论了这四种类型的NoSQL的特点以及适用场景 需要NoSQL的理由 NoSQL数据库 看起来
  • Qt程序设置不重复打开该程序

    Qt程序设置不重复打开该程序 文章目录 Qt程序设置不重复打开该程序 对于已经打开的Qt桌面程序 我们希望用户再次双击桌面的快捷方式时 程序可以自动激活到其他所有程序的最前面 而不是重新打开一次程序 此时我们采用QSharedMemory方
  • 【图像处理】【去模糊】图像去模糊之初探--Single Image Motion Deblurring

    原文 原文地址 曾经很长一段时间 对图像去模糊都有一种偏见 认为这是一个灌水的领域 没有什么实用价值 要到这样的文章 不管是多高的档次 直接pass 最近在调研最近几年的关于Computational Photography的一些研究热点时
  • 莫言用 GPT 写颁奖辞,那如果他自己写会是什么效果呢?

    在 收获 杂志 65 周年庆典上 莫言在为余华颁奖时表示 余华是自己的好朋友 但给他的颁奖词写了好几天也想不出来 后来找了 ChatGPT 帮忙写 最后 莫言让 ChatGPT 写了一篇莎士比亚风格 1000 多字的颁奖词 输入了关键词 活
  • 数据仓库_缓慢渐变维_拉链表(全揭秘)

    这篇文章我们主要讲解下以下几个点 什么是拉链表 用于什么样的场景 拉链表的示例 如何获取某一天的历史状态 如何在使用维度拉链表并使用代理键的前提下 构建含维度代理键的事实表 1 什么是拉链表 用于什么样的场景 当维度数据发生变化时 将旧数据
  • Hutool:一行代码搞定数据脱敏

    1 什么是数据脱敏 1 1 数据脱敏的定义 数据脱敏百度百科中是这样定义的 数据脱敏 指对某些敏感信息通过脱敏规则进行数据的变形 实现敏感隐私数据的可靠保护 这样就可以在开发 测试和其它非生产环境以及外包环境中安全地使用脱敏后的真实数据集
  • 枭龙智能眼镜 XLOONG X100 Glass拆解

    这里只拆到主板过 首先需要对带Glass的可拆卸配件进行壳体加热 主机外壳有密封胶 吹风机对主机外壳的接缝处进行加热 可以从下侧的点开始用撬棒拆 拆开一个角之后沿着边慢慢打开 如果还是有阻尼感打不开 用吹风机加热再慢慢撬开 但是注意 打开幅
  • MySQL备份与恢复

    目录 数据库备份的分类 数据备份的重要性 数据库备份的分类 常见的备份方法 MySQL完全备份与恢复 MySQL完全备份介绍 MySQL完全备份的优缺点 数据库完全备份分类 完全备份操作 物理冷备份 逻辑备份 mysqldump的使用 My
  • python3.6打包成exe可执行文件,已解决方案

    将python程序打包成exe可执行文件有多种方法 这里讲一种最简单最常用的方法 只需要使用pyinstaller命令即可 一 环境 Windows 7或10 x64 Python 3 6 1 二 需要包 pyinstaller 3 3 p
  • JSON.stringify && JSON.parse

    原生JS 通过 ajax请求数据的时候控制台报500的错误 在这里记录一下 不喜勿喷哈 let submit document getElementsByClassName submit 0 submit addEventListener
  • idea突然打不开【解决方法整理总结】

    今天突发情况打不开 下面分情况讨论 欢迎大家给出不同的错误版本 狗头 一直这样 每天一遍qwq 解决方案 可以先找到idea安装根目录bin下 选中idea bat右键编辑 或者使用txt打开在idea bat最后一行添加 pause 打印
  • 解决pythoncharm中安装numpy无法调用的问题

    1 提示ImportError numpy core multiarray failed to import 可能问题 numpy的版本不合适 解决方法 1 卸载安装的numpy安装新的版本 pip uninstall numpy pip
  • 稀疏奖励及模仿学习(DataWhale组队学习笔记)

    稀疏奖励 在用强化学习解决现实问题时 我们对学习目标设置相应的奖励 但在庞大的状态空间中 智能体想要通过随机试错来获取奖励的概率是极低的 不获得奖励就没办法学习 我们将这种情况称作稀疏奖励 针对稀疏奖励问题 我们介绍以下几种解决方案 1 R
  • React脚手架

    React脚手架 xxx脚手架 用来帮助程序员快速创建一个基于xxx库的模板项目 包含了所有需要的配置 语法检查 jsx编译 devServer 下载好了所有相关的依赖 可以直接运行一个简单效果 react提供了一个用于创建react项目的
  • 传奇服务器开启生肖系统,英雄合击十二生肖商业版[带补丁]

    英雄合击十二生肖商业版 带补丁 新增功能 最新梦幻十二生肖 新模型 新样式 新一年的开始 多种表情 更强的脚本功能 长久寿命 返回不败传奇时代 加入新地图 精灵城 机械城 机械城下 怪物等级显示 支持原有 卧龙 英雄 合击 新技能 护体盾
  • 哈夫曼树与哈夫曼编码及等长编码

    哈夫曼树的构造 就是将给定的数据中选择最小的两个权值进行合并 然后重复该操作 构造出一个二叉树 使其带权路径长度WPL最小的二叉树称为哈夫曼树或最优二叉树 例如 给定几个数值 0 07 0 19 0 02 0 06 0 32 0 03 0
  • webFlux运算符决策树-个人翻译

    目录 创建新的序列 转换现有的序列 窥探序列 Peek 过滤序列 filter 错误处理 时间相关处理 分割一个序列 同步的操作 Flux广播给多个订阅者 Reactor运算符决策树 创建新的序列 发布已经获取的T just Flux Mo
  • 彻底解决Qt报错:无法定位程序输入点于动态链接库

    一 问题描述 前段时间使用Qt Creator写程序 在最后打包的时候出错 期间尝试修改环境变量的顺序 后来发现不是环境变量的问题 但问题解决后并未将环境变量改回 导致今天使用VS2019联合Qt编译之前程序 之前已验证正确 的时候报错 具
  • alter table move跟shrink space的区别

    author skate time2010 05 28 alter table move跟shrink space的区别 今天主要从两点说他们的区别 1 碎片的整理 2 空间的收缩 SQL gt select from v version
  • 线性表的查找

    1 顺序查找 1 顺序查找介绍 顺序查找的查找过程为 从表的一端开始 依次将记录的关键字和给定的值进行比较 若某个记录的关键字和给定的值是一样的 则查找成功 反之 若扫描整个表之后 任然没有找到关键字和给定的值相等的记录 则查找失败 适用用