【C++数据结构——查找】二分查找(头歌实践教学平台习题)【合集】

news2025/1/8 19:37:12

目录😋

任务描述

相关知识

一、根据键盘输入的一组有序数据建立顺序表

二、顺序表的输出

三、二分查找算法

测试说明

通关代码

测试结果


任务描述

本关任务:实现二分查找的算法。

相关知识

为了完成本关任务,你需要掌握:

  1. 根据键盘输入的一组有序数据建立顺序表
  2. 顺序表的输出
  3. 二分查找算法

一、根据键盘输入的一组有序数据建立顺序表

  1. 顺序表的概念
    顺序表是线性表的一种存储方式,它用一组地址连续的存储单元依次存储线性表中的数据元素,使得逻辑上相邻的元素在物理存储位置上也相邻。在 C/C++ 等编程语言中,可以使用数组来实现顺序表的底层存储结构。

  2. 建立顺序表的步骤(以 C++ 为例)

  • 定义顺序表结构体
    首先需要定义一个结构体来表示顺序表,结构体中通常包含存储数据的数组、当前顺序表的长度等信息。以下是一个简单的示例代码:
#define MAX_SIZE 100  // 定义顺序表的最大容量

template <typename T>
struct SeqList {
    T data[MAX_SIZE];  // 存储数据的数组
    int length;        // 顺序表当前长度
    SeqList() : length(0) {}  // 构造函数初始化长度为 0
};
  • 从键盘输入数据并构建顺序表
    可以通过cin等输入流来获取用户从键盘输入的数据,然后将这些有序数据依次存入顺序表中,同时更新顺序表的长度。以下是一个简单的代码示例,假设输入的是整数类型的数据且以特定结束标志(比如输入 -1 表示结束输入):
#include <iostream>
using namespace std;

template <typename T>
void createSeqList(SeqList<T>& list) {
    T num;
    cout << "请输入有序数据(输入 -1 结束输入):" << endl;
    while (cin >> num && num!= -1) {
        if (list.length < MAX_SIZE) {
            list.data[list.length++] = num;
        } else {
            cout << "顺序表已满,无法继续添加元素。" << endl;
            break;
        }
    }
}

二、顺序表的输出

输出顺序表就是将顺序表中存储的元素依次展示出来。同样以 C++ 为例,通过遍历顺序表结构体中的数组,按照顺序输出每个元素,示例代码如下:

template <typename T>
void printSeqList(const SeqList<T>& list) {
    cout << "顺序表中的元素为:";
    for (int i = 0; i < list.length; i++) {
        cout << list.data[i] << " ";
    }
    cout << endl;
}

main函数中,可以这样调用上述创建和输出顺序表的函数:

int main() {
    SeqList<int> myList;
    createSeqList(myList);
    printSeqList(myList);
    return 0;
}

三、二分查找算法

  1. 算法原理
    二分查找(也叫折半查找)是一种用于在有序数组(或者说顺序表这种存储有序数据的结构)中查找特定元素的高效算法。它的基本思想是:每次比较中间元素与目标元素的大小,如果中间元素等于目标元素,则查找成功;如果中间元素大于目标元素,则在数组的左半部分继续查找;如果中间元素小于目标元素,则在数组的右半部分继续查找。不断重复这个过程,直到找到目标元素或者确定目标元素不存在为止。

  2. 算法实现步骤(以在上述顺序表中查找为例)
    以下是使用 C++ 实现二分查找算法的代码示例:可以在main函数中调用二分查找函数来查找特定元素,示例如下:

    template <typename T>
    int binarySearch(const SeqList<T>& list, T target) {
        int left = 0;  // 左边界
        int right = list.length - 1;  // 右边界
        while (left <= right) {
            int mid = left + (right - left) / 2;  // 计算中间位置,防止溢出
            if (list.data[mid] == target) {
                return mid;  // 找到目标元素,返回其下标
            } else if (list.data[mid] > target) {
                right = mid - 1;  // 在左半部分继续查找
            } else {
                left = mid + 1;  // 在右半部分继续查找
            }
        }
        return -1;  // 未找到目标元素,返回 -1
    }
    

    可以在main函数中调用二分查找函数来查找特定元素,示例如下:

  3. 算法复杂度分析

  • 时间复杂度:在最好情况下,一次比较就能找到目标元素,时间复杂度为O(1);在最坏情况下,需要不断地对半划分区间,直到区间缩小为 1,此时时间复杂度为 O(logn),其中  是顺序表中元素的个数。平均时间复杂度也是 O(logn),所以二分查找算法在有序数据查找场景下效率较高。

  • 空间复杂度:由于算法在查找过程中只需要使用几个额外的变量(如左右边界、中间位置指针等)来辅助查找,不随数据规模增长而大量占用额外空间,所以空间复杂度为O(1)

测试说明

平台会对你编写的代码进行测试:

测试输入示例:(第一行是输入的一组原始关键字数据,第二行是要查找的关键字)

1 2 3 4 5 6 7 8 9 10 
9

预期输出:

请输入一组数据 : 关键字序列:1 2 3 4 5 6 7 8 9 10
请输入要查找的关键字 :9
查找9的比较过程如下:
第1次比较:在[0,9]中比较元素R[4]:5
 第2次比较:在[5,9]中比较元素R[7]:8
 第3次比较:在[8,9]中比较元素R[8]:9
元素9的位置是9

提示:二分查找算法中要依次输出每次查找的区间,及与k所比较的关键字,用空格分隔开。假设顺序表的关键字序列: 2 3 10 15 20 25 28 29 30 35 40,

如果要查找的关键字k=20,则函数输出如下,并返回值5.
第1次比较: 查找范围R[0...10],比较元素R[5]:25
第2次比较: 查找范围R[0...4],比较元素R[2]:10
第3次比较: 查找范围R[3...4],比较元素R[3]:15
第4次比较: 查找范围R[4...4],比较元素R[4]:20

如果要查找的关键字k=26,则函数要输出如下,并返回值0.
第1次比较: 查找范围R[0...10],比较元素R[5]:25
第2次比较: 查找范围R[6...10],比较元素R[8]:30
第3次比较: 查找范围R[6...7],比较元素R[6]:28

开始你的任务吧,祝你成功!


通关代码

#include <iostream>
#include <vector>
using namespace std;
// 定义查找元素的结构体类型,包含关键字和其他数据(这里暂未详细使用其他数据部分)
struct RecType {
  int key;
  // 可以按需添加其他数据成员及对应操作,此处简化只关注关键字key
};

// 创建顺序表,将输入的关键字数据存入顺序表中
void CreateList(vector<RecType> &R, const vector<int> &keys) {
  for (size_t i = 0; i < keys.size(); ++i) {
    RecType temp;
    temp.key = keys[i];
    R.push_back(temp);
  }
}

// 输出顺序表的函数,遍历顺序表并输出每个元素的关键字
void DispList(const vector<RecType> &R) {
  for (size_t i = 0; i < R.size(); ++i) {
    cout << R[i].key << " ";
  }
  cout << endl;
}

// 二分查找算法实现,按照要求输出每次查找的区间及比较的关键字
int BinSearch(const vector<RecType> &R, int k) {
  int low = 0;
  int high = R.size() - 1;
  int count = 1;
  while (low <= high) {
    int mid = low + (high - low) / 2;
    cout << "  第" << count << "次比较:在[" << low << "," << high
         << "]中比较元素R[" << mid << "]:" << R[mid].key << endl;
    if (R[mid].key == k) {
      return mid + 1; // 返回位置,这里的位置是从1开始计数,所以下标加1
    } else if (R[mid].key > k) {
      high = mid - 1;
    } else {
      low = mid + 1;
    }
    count++;
  }
  return 0; // 如果没找到,返回0表示元素不在表中
}

int main() {
  vector<RecType> R;
  vector<int> keys;
  int n =
      10; // 根据测试示例,这里默认输入数据个数为10,也可以改成让用户输入个数
  cout << "请输入一组数据 :" << endl;
  for (int i = 0; i < n; ++i) {
    int num;
    cin >> num;
    keys.push_back(num);
  }
  CreateList(R, keys);
  cout << "关键字序列:";
  DispList(R);
  int k;
  cin >> k;
  cout << "请输入要查找的关键字 :" << k << endl;
  cout << "查找" << k << "的比较过程如下:" << endl;
  int result = BinSearch(R, k);
  if (result != 0) {
    cout << "元素" << k << "的位置是" << result << endl;
  } else {
    cout << "元素" << k << "不在表中" << endl;
  }
  return 0;
}

测试结果

在这里插入图片描述

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

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

相关文章

20250103在Ubuntu20.04.5的Android Studio 2024.2.1.12中跑通Hello World

20250103在Ubuntu20.04.5的Android Studio 2024.2.1.12中跑通Hello World 2025/1/3 14:06 百度&#xff1a;android studio helloworld android studio hello world kotlin helloword kotlin 串口 no run configurations added android studio no run configurations added 1、…

卸载干净 IDEA(图文讲解)

目录 1、卸载 IDEA 程序 2、注册表清理 3、残留清理 1、卸载 IDEA 程序 点击屏幕左下角 Windows 图标 -> 设置-控制面板->intellij idea 勾选第一栏 Delete IntelliJ IDEA 2022.2 caches and local history&#xff0c;表示同时删除 IDEA 本地缓存以及历史。 Delete I…

【HarmonyOS】鸿蒙应用实现屏幕录制详解和源码

【HarmonyOS】鸿蒙应用实现屏幕录制详解和源码 一、前言 官方文档关于屏幕录制的API和示例介绍获取简单和突兀。使用起来会让上手程度变高。所以特意开篇文章&#xff0c;讲解屏幕录制的使用。官方文档参见&#xff1a;使用AVScreenCaptureRecorder录屏写文件(ArkTS) 二、方…

我的创作纪念日——《惊变128天》

我的创作纪念日——《惊变128天》 机缘收获日常成就憧憬 机缘 时光飞逝&#xff0c;转眼间&#xff0c;我已在这条创作之路上走过了 128 天。回顾起 2024 年 8 月 29 日&#xff0c;我满怀忐忑与期待&#xff0c;撰写了第一篇技术博客《讲解LeetCode第1题&#xff1a;两数之和…

stm32第一次烧录或者上电运行卡死问题分析

问题描述 单片机烧录代码&#xff08;刚上电&#xff09;无法立即运行&#xff0c;必须要复位一次或多次才能运行&#xff1b;跟踪调试会进入HardFault_Handler中断。 问题分析 烧录配置如下图&#xff0c;首先排除配置问题那么该问题就比较让人头大了&#xff0c;理论上&am…

YOLOV8训练好的best.pt模型转best.onnx并部署成python可调用

今天这篇博文是学习大佬作品以后&#xff0c;执行我的需求后的总结&#xff0c;做了一些代码调整&#xff0c;就此记录一下&#xff0c;非常感谢大佬提供如此好的输出。 已知yolov8 训练好的模型一般是pt格式&#xff0c;比如best.pt&#xff0c;现在我期望这个模型可以转成可以…

君正T41交叉编译ffmpeg、opencv并做h264软解,利用君正SDK做h264硬件编码

目录 1 交叉编译ffmpeg----错误解决过程&#xff0c;不要看 1.1 下载源码 1.2 配置 1.3 编译 安装 1.3.1 报错&#xff1a;libavfilter/libavfilter.so: undefined reference to fminf 1.3.2 报错&#xff1a;error: unknown type name HEVCContext; did you mean HEVCPr…

基于ASP.NET的动漫网站

一、系统架构与技术实现 系统架构&#xff1a;基于ASP.NET的MVC框架构建&#xff0c;实现网站的层次结构&#xff0c;使得网站更加易于维护和扩展。 技术实现&#xff1a;利用ASP.NET的技术特点&#xff0c;如强大的后端开发能力、丰富的UI控件等&#xff0c;结合前端技术如HT…

「Java 数据结构全面解读」:从基础到进阶的实战指南

「Java 数据结构全面解读」&#xff1a;从基础到进阶的实战指南 数据结构是程序设计中的核心部分&#xff0c;用于组织和管理数据。Java 提供了丰富的集合框架和工具类&#xff0c;涵盖了常见的数据结构如数组、链表、栈、队列和树等。本文将系统性地介绍这些数据结构的概念、…

安卓NDK视觉开发——手机拍照文档边缘检测实现方法与库封装

一、项目创建 创建NDK项目有两种方式&#xff0c;一种从新创建整个项目&#xff0c;一个在创建好的项目添加NDK接口。 1.创建NDK项目 创建 一个Native C项目&#xff1a; 选择包名、API版本与算法交互的语言&#xff1a; 选择C版本&#xff1a; 创建完之后&#xff0c;可…

MATLAB仿真:基于GS算法的经大气湍流畸变涡旋光束波前校正仿真

GS算法流程 GS&#xff08;Gerchberg-Saxton&#xff09;相位恢复算法是一种基于傅里叶变换的最速下降算法&#xff0c;可以通过输出平面和输入平面上光束的光强分布计算出光束的相位分布。图1是基于GS算法的涡旋光束畸变波前校正系统框图&#xff0c;在该框图中&#xff0c;已…

【React+TypeScript+DeepSeek】穿越时空对话机

引言 在这个数字化的时代&#xff0c;历史学习常常给人一种距离感。教科书中的历史人物似乎永远停留在文字里&#xff0c;我们无法真正理解他们的思想和智慧。如何让这些伟大的历史人物"活"起来&#xff1f;如何让历史学习变得生动有趣&#xff1f;带着这些思考&…

深入刨析数据结构之排序(上)

目录 1.内部排序 1.1概述 1.2插入排序 1.2.1其他插入排序 1.2.1.1 折半插入排序 1.2.1.2 2-路插入排序 1.3希尔排序 1.4快速排序 1.4.1起泡排序 1.4.2快速排序 1.4.2.1hoare版本 1.4.2.2挖坑版本 1.4.2.3前后指针版本 1.4.2.4优化版本 1.4.2.4.1小区间插入排序优…

AIA - APLIC之三(附APLIC处理流程图)

本文属于《 RISC-V指令集基础系列教程》之一,欢迎查看其它文章。 1 APLIC复位 APLIC复位后,其所有状态都变得有效且一致,但以下情况除外: 每个中断域的domaincfg寄存器(spec第 4.5.1 节);可能是machine-level interrupt domain的MSI地址配置寄存器(spec第4.5.3 和4.5…

openwrt 清缓存命令行

一、查看缓存 &#xff1a; free -m 二、清缓存&#xff1a;echo 3 > /proc/sys/vm/drop_caches  三、详解。 释放物理页缓存 echo 1 > /proc/sys/vm/drop_caches 释放可回收的slab对象&#xff0c;包含inode and dentry echo 2 > /proc/sys/vm/drop_caches 同时…

Linux -- 端口号、套接字、网络字节序、sockaddr 结构体

目录 什么是端口号&#xff1f; 什么是套接字&#xff1f; 网络字节序 struct sockaddr 结构体 什么是端口号&#xff1f; 我们日常上网的时候&#xff0c;主机其实是在进行两种操作&#xff1a; 1、把远端的数据拉取到本地&#xff0c;比如刷抖音的时候&#xff0c;手机向…

《数据结构》期末考试测试题【中】

《数据结构》期末考试测试题【中】 21.循环队列队空的判断条件为&#xff1f;22. 单链表的存储密度比1&#xff1f;23.单链表的那些操作的效率受链表长度的影响&#xff1f;24.顺序表中某元素的地址为&#xff1f;25.m叉树第K层的结点数为&#xff1f;26. 在双向循环链表某节点…

实际开发中,常见pdf|word|excel等文件的预览和下载

实际开发中,常见pdf|word|excel等文件的预览和下载 背景相关类型数据之间的转换1、File转Blob2、File转ArrayBuffer3、Blob转ArrayBuffer4、Blob转File5、ArrayBuffer转Blob6、ArrayBuffer转File 根据Blob/File类型生成可预览的Base64地址基于Blob类型的各种文件的下载各种类型…

《Opencv》基础操作详解(4)

接上篇&#xff1a;《Opencv》基础操作详解&#xff08;3&#xff09;-CSDN博客 目录 22、图像形态学操作 &#xff08;1&#xff09;、顶帽&#xff08;原图-开运算&#xff09; 公式&#xff1a; 应用场景&#xff1a; 代码示例&#xff1a; &#xff08;2&#xff09;…

大数据高级ACP学习笔记(2)

钻取&#xff1a;变换维度的层次&#xff0c;改变粒度的大小 星型模型 雪花模型 MaxCompute DataHub