目录😋
任务描述
本关任务:实现二分查找的算法。
相关知识
为了完成本关任务,你需要掌握:
- 根据键盘输入的一组有序数据建立顺序表
- 顺序表的输出
- 二分查找算法
一、根据键盘输入的一组有序数据建立顺序表
顺序表的概念
顺序表是线性表的一种存储方式,它用一组地址连续的存储单元依次存储线性表中的数据元素,使得逻辑上相邻的元素在物理存储位置上也相邻。在 C/C++ 等编程语言中,可以使用数组来实现顺序表的底层存储结构。
建立顺序表的步骤(以 C++ 为例)
- 定义顺序表结构体 :
首先需要定义一个结构体来表示顺序表,结构体中通常包含存储数据的数组、当前顺序表的长度等信息。以下是一个简单的示例代码:
cpp#define MAX_SIZE 100 // 定义顺序表的最大容量 template <typename T> struct SeqList { T data[MAX_SIZE]; // 存储数据的数组 int length; // 顺序表当前长度 SeqList() : length(0) {} // 构造函数初始化长度为 0 };
- 从键盘输入数据并构建顺序表 :
可以通过cin
等输入流来获取用户从键盘输入的数据,然后将这些有序数据依次存入顺序表中,同时更新顺序表的长度。以下是一个简单的代码示例,假设输入的是整数类型的数据且以特定结束标志(比如输入 -1 表示结束输入):
cpp#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++ 为例,通过遍历顺序表结构体中的数组,按照顺序输出每个元素,示例代码如下:
cpptemplate <typename T> void printSeqList(const SeqList<T>& list) { cout << "顺序表中的元素为:"; for (int i = 0; i < list.length; i++) { cout << list.data[i] << " "; } cout << endl; }
在
main
函数中,可以这样调用上述创建和输出顺序表的函数:
cppint main() { SeqList<int> myList; createSeqList(myList); printSeqList(myList); return 0; }
三、二分查找算法
算法原理
二分查找(也叫折半查找)是一种用于在有序数组(或者说顺序表这种存储有序数据的结构)中查找特定元素的高效算法。它的基本思想是:每次比较中间元素与目标元素的大小,如果中间元素等于目标元素,则查找成功;如果中间元素大于目标元素,则在数组的左半部分继续查找;如果中间元素小于目标元素,则在数组的右半部分继续查找。不断重复这个过程,直到找到目标元素或者确定目标元素不存在为止。
算法实现步骤(以在上述顺序表中查找为例)
以下是使用 C++ 实现二分查找算法的代码示例:可以在
main
函数中调用二分查找函数来查找特定元素,示例如下:
cpptemplate <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
函数中调用二分查找函数来查找特定元素,示例如下:算法复杂度分析
时间复杂度 :在最好情况下,一次比较就能找到目标元素,时间复杂度为;在最坏情况下,需要不断地对半划分区间,直到区间缩小为 1,此时时间复杂度为 ,其中 是顺序表中元素的个数。平均时间复杂度也是 ,所以二分查找算法在有序数据查找场景下效率较高。
空间复杂度 :由于算法在查找过程中只需要使用几个额外的变量(如左右边界、中间位置指针等)来辅助查找,不随数据规模增长而大量占用额外空间,所以空间复杂度为。
测试说明
平台会对你编写的代码进行测试:
测试输入示例: (第一行是输入的一组原始关键字数据,第二行是要查找的关键字)
cpp1 2 3 4 5 6 7 8 9 10 9
预期输出:
cpp请输入一组数据 : 关键字序列: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
开始你的任务吧,祝你成功!
通关代码
cpp
#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;
}