6-8 分钟
拆解二分查找
核心重难点
取中间值比较 · 每次缩小一半范围 · 有序数组高效查找
效率远超顺序查找的经典折半查找算法
同学们大家好!二分查找法也称为折半查找算法,是一种在有序数组中查找目标值的高效算法。它的核心思想是取有序数组的中间元素与目标值比较,每次将搜索范围缩小一半。今天这节微课,我们就逐层拆解二分查找的所有重点和难点。
Contents · 本课内容
4 大模块 · 全流程覆盖
从原理到实训,让你独立看懂、理解通透、会写会改代码
01
核心算法思想 + 折半查找逻辑
取中间值、比较、缩小一半范围、循环直至找到
02
代码编写 + while循环与三指针
left/right/mid 三个指针、while条件、break跳出
03
实训案例:7个有序数查找
数组 [3,5,9,18,27,36,65] 二分查找全流程
04
VS2010 示范操作 + 完整代码
新建项目到运行调试,手把手实操
本节课我们将逐一攻克4大模块:核心算法思想与折半查找逻辑、代码编写与while循环、实训案例、以及VS2010示范操作。循序渐进,零基础也能轻松学懂二分查找。
重点突破 · 01
二分查找
核心算法思想
取中间元素比较,每次缩小一半搜索范围,前提是数组必须有序
首先我们掌握本节课第一个核心重点:二分查找的算法思想。二分查找的基本思想是取有序数组的中间元素k与待查找数值x进行比较,若相等返回中间元素k的下标,若不相等则根据数组排序方式确定待查找数值x可能存在的位置。由于每次都将搜索范围缩小一半,因此算法效率非常高。但前提条件是数组必须是有序的。
核心原理 · 取中间值 → 比较 → 缩小一半范围
以有序数组 [3, 5, 9, 18, 27, 36, 65] 为例
场景1:查找 27(找到)
场景2:查找 10(没找到)
查找目标 x =
27
left =0
right =6
mid =3
arr[mid] =18
当前轮次:-
当前步骤:-
查找结果:待查找
我们以有序数组3、5、9、18、27、36、65为例。场景1查找27:初始left=0,right=6,mid=(0+6)/2=3,arr[3]=18,27大于18所以在右半区,left=mid+1=4。第二轮left=4,right=6,mid=5,arr[5]=36,27小于36所以在左半区,right=mid-1=4。第三轮left=4,right=4,mid=4,arr[4]=27等于27,找到了!场景2查找10:经过三轮比较后left=3大于right=2,循环结束,没找到。
难点突破 · 01
三指针与
while循环
left / right / mid 三指针配合 while 循环,每次折半缩小范围
理解了算法思想,我们攻克本节课的难点:三指针与while循环。二分查找与顺序查找最大的区别在于它使用left、right、mid三个指针来控制搜索范围,通过while循环不断折半,而不是逐个遍历。
难点突破 · 三指针 + while循环
left / right / mid 三指针各司其职
二分查找核心口诀:算mid、比arr[mid]、缩小一半范围
三个指针
🎯 left / right / mid
- left:搜索范围左边界,初始为 0
- right:搜索范围右边界,初始为 n-1
- mid:中间位置,mid = (left + right) / 2
- C# 整数除法自动取整,无需额外处理
mid = (left + right) / 2;
while + break
🔄 while循环 + 范围缩小
- 条件:while (left <= right)
- 若 num == arr[mid]:找到,break 跳出
- 若 num < arr[mid]:在左半区,right = mid - 1
- 若 num > arr[mid]:在右半区,left = mid + 1
while (left <= right)
关键理解:每次循环都将搜索范围缩小一半——n个元素最多只需 log₂n 次比较,7个元素最多3次即可找到
二分查找使用三个指针。left是搜索范围左边界,初始为0。right是搜索范围右边界,初始为n-1。mid是中间位置,等于(left+right)/2,C#中整数除法自动取整。while循环条件是left<=right,只要范围还有元素就继续。如果num等于arr[mid]就找到并break。如果num小于arr[mid]说明目标在左半区,right=mid-1。如果num大于arr[mid]说明目标在右半区,left=mid+1。每次循环范围缩小一半,7个元素最多3次比较就能找到。
难点突破 · 每次缩小一半
查找 27 的范围变化过程
7 个元素 → 3 个元素 → 1 个元素,最多 3 轮
1
第 1 轮:全范围查找
left=0, right=6, mid=3, arr[3]=18。27 > 18,目标在右半区,left = mid+1 = 4
范围 [0, 6] → 7 个元素
2
第 2 轮:右半区查找
left=4, right=6, mid=5, arr[5]=36。27 < 36,目标在左半区,right = mid-1 = 4
范围 [4, 6] → 3 个元素
3
第 3 轮:定位到目标
left=4, right=4, mid=4, arr[4]=27。27 == 27,找到!输出"第5个元素",break 跳出
范围 [4, 4] → 1 个元素 ✅
效率对比:顺序查找最坏需比较 7 次,二分查找最多只需 3 次(log₂7 ≈ 2.8)。数据量越大,优势越明显——100万个数据,顺序查找最坏100万次,二分查找最多仅20次!
这是查找27时搜索范围的变化过程。第1轮全范围7个元素,mid=3,arr[3]=18,27大于18所以在右半区,left变成4。第2轮范围缩小到3个元素[4,6],mid=5,arr[5]=36,27小于36所以在左半区,right变成4。第3轮范围缩小到1个元素[4,4],mid=4,arr[4]=27等于27,找到了!只需3轮。对比顺序查找最坏需要7次比较,数据量越大二分查找的优势越明显。
代码实战
C# 代码
逐行分析
数组定义 → 输出数组 → 输入目标 → while循环查找 → 结果输出
接下来我们进入代码实战环节,逐行分析二分查找的C#代码。代码分为五个部分:定义有序数组、输出原始数组、接收用户输入、while循环查找、输出结果。
代码实战 · 逐行拆解
二分查找完整代码
重点关注:while条件、mid计算、三种比较分支、left>right判断
static void Main(string[] args)
{
// 1. 定义有序数组
int[] arr = new int[] { 3, 5, 9, 18, 27, 36, 65 };
int num, i, left, right, mid;
// 2. 输出原始数组
Console.WriteLine("***二分查找法***");
Console.WriteLine("数组中数据为:");
for (i = 0; i <= 6; i++)
{
Console.Write(arr[i] + " ");
}
Console.WriteLine();
// 3. 接收用户输入
Console.Write("请输入待查找数据:");
num = int.Parse(Console.ReadLine());
// 4. 初始化指针 + while循环查找
left = 0;
right = 6;
while (left <= right)
{
// C#中,除法运算符两端为整型,则计算结果自动取整
mid = (left + right) / 2;
if (num == arr[mid])
{
Console.WriteLine("找到了!该数字是数组中第{0}个元素", mid + 1);
break;
}
else if (num < arr[mid]) right = mid - 1;
else left = mid + 1;
}
// 5. 判断未找到
if (left > right) Console.WriteLine("没找到");
Console.ReadLine();
}
这段代码分为5个部分。第1部分定义有序数组arr,7个元素从小到大排列。第2部分用for循环输出原始数组。第3部分用Console.Write提示用户输入,用int.Parse转为整数存入num。第4部分是核心查找逻辑:初始化left=0,right=6,while循环只要left<=right就继续。每次算mid=(left+right)/2,如果num等于arr[mid]就找到并break,如果num小于arr[mid]就right=mid-1,否则left=mid+1。第5部分循环结束后判断if(left>right)说明没找到。
代码实战 · 关键点深度解读
3 个关键代码段
🔢
中间值计算
mid = (left + right) / 2
C#中整数除法自动取整。如(0+6)/2=3,(4+6)/2=5。无需调用Math.Floor。mid是搜索范围的中间位置。
⚖️
三分支比较
== → 找到break
< → right=mid-1
> → left=mid+1
三种情况:等于找到;小于在左半区查找,right左移;大于在右半区查找,left右移。注意mid-1和mid+1,跳过已比较的mid。
🔍
循环结束判断
while(left <= right)
if(left > right) → 没找到
while条件left<=right:范围还有元素就继续。如果break跳出则找到;如果条件不满足退出则left>right,说明没找到。
💡 易错提醒:缩小范围时用的是 mid - 1 和 mid + 1,而不是 mid。因为 arr[mid] 已经比较过且不等于目标,必须跳过它,否则可能死循环!
这里有3个关键代码段。第一个是mid的计算,(left+right)/2在C#中整数除法自动取整,不需要额外处理。第二个是三分支比较:等于找到并break,小于则right=mid-1在左半区查找,大于则left=mid+1在右半区查找。第三个是循环结束判断,while条件是left<=right,break跳出说明找到,条件不满足退出说明left>right即没找到。特别提醒:缩小范围时必须用mid-1和mid+1,不能直接用mid,因为arr[mid]已经比较过了,不跳过它可能导致死循环。
实训案例 · 【实训4-2】
二分查找
实训实战
有序数组 [3, 5, 9, 18, 27, 36, 65] · 用户输入数字查找
现在进入实训环节。实训内容是:在给定有序数组arr中查找一个用户输入的数字,若找到则输出"找到了!"并给出该数字在数组中的位置,若未找到则输出"没找到"。
实训4-2 · 算法步骤分析
二分查找算法步骤
前提条件:数组必须有序(由小到大排序)
1
定义有序数组
声明有序 int 数组 arr:3, 5, 9, 18, 27, 36, 65(已从小到大排列)
2
输出数组 + 输入
用 for 循环输出数组元素,提示用户输入待查找的数字 num
3
初始化指针
设置 left=0(左边界),right=6(右边界),准备开始折半查找
4
while循环查找
计算 mid=(left+right)/2,比较 num 与 arr[mid],缩小一半范围
5
判断结果
break 跳出 → 找到了;left > right 循环结束 → 没找到
算法特点:二分查找每次将搜索范围缩小一半,效率非常高。但前提条件是数组必须是有序的,否则算法无法正确工作。7个元素最多只需3次比较。
实训分析:二分查找法的基本思想是取有序数组的中间元素k与待查找数值x进行比较,若相等返回中间元素k的下标,若不相等则根据数组排序方式确定待查找数值x可能存在的位置。由于每次都将搜索范围缩小一半,因此算法效率非常高。但前提条件是数组必须是有序的。我们分5步完成:定义有序数组、输出数组并输入、初始化指针、while循环查找、判断结果。
VS2010 · 新建项目操作步骤
新建项目 + 编写代码
运行 Visual Studio 2010步骤1
双击桌面 Microsoft Visual Studio 2010 图标,启动开发环境
新建项目步骤2
选择菜单项"文件" → "新建" → "项目",打开"新建项目"对话框
选择项目类型步骤3
在左侧选择"Visual C#"下的"Windows",在模板列表中选择"控制台应用程序"
输入代码步骤4
系统进入代码编辑环境后,在 static void Main(string[] args) 代码段中输入二分查找代码
运行调试步骤5
按 F5 或点击工具栏"启动调试"按钮,运行程序并测试查找功能
示范操作步骤:第一步运行Microsoft Visual Studio 2010。第二步选择菜单项"文件"-"新建"-"项目",打开"新建项目"对话框。第三步选择"Visual C#"下的"Windows",在模板列表选择"控制台应用程序"。第四步在static void Main(string[] args)代码段中输入二分查找代码。第五步按F5运行调试。
实训代码 · 完整实现
7 个有序数二分查找完整代码
在 Main 方法中输入以下代码
static void Main(string[] args)
{
int[] arr = new int[] { 3, 5, 9, 18, 27, 36, 65 };
int num, i, left, right, mid;
Console.WriteLine("***二分查找法***");
Console.WriteLine("数组中数据为:");
for (i = 0; i <= 6; i++)
{
Console.Write(arr[i] + " ");
}
Console.WriteLine();
Console.Write("请输入待查找数据:");
num = int.Parse(Console.ReadLine());
left = 0;
right = 6;
// 在数组arr中查找输入的数据num
while (left <= right)
{
// C#中,除法运算符两端为整型,则计算结果自动取整
mid = (left + right) / 2;
if (num == arr[mid])
{
Console.WriteLine("找到了!该数字是数组中第{0}个元素", mid + 1);
break;
}
else if (num < arr[mid]) right = mid - 1;
else left = mid + 1;
}
if (left > right) Console.WriteLine("没找到");
Console.ReadLine();
}
> ***二分查找法***
> 数组中数据为:
3 5 9 18 27 36 65
> 请输入待查找数据:27
找到了!该数字是数组中第5个元素
────────────────────────
> ***二分查找法***
> 数组中数据为:
3 5 9 18 27 36 65
> 请输入待查找数据:10
没找到
这是完整的实训代码。定义有序数组arr有7个元素3、5、9、18、27、36、65。先输出原始数组。然后接收用户输入的数字num。初始化left=0,right=6。while循环中每次计算mid=(left+right)/2,如果num等于arr[mid]就输出"找到了!该数字是数组中第mid+1个元素"并break。如果num小于arr[mid]就right=mid-1,否则left=mid+1。循环结束后如果left>right输出"没找到"。运行结果展示两种情况:输入27找到第5个元素,输入10没找到。
Summary · 核心口诀总结
五大要点,一次吃透二分查找
从原理到实训,截图保存随时复习
1
前提条件
数组必须有序!二分查找只在有序数组上有效,无序数组需先排序
2
三指针
left=0, right=n-1, mid=(left+right)/2,整数除法自动取整
3
三分支比较
==找到break;<则right=mid-1;>则left=mid+1(注意跳过mid)
4
循环与判断
while(left<=right)控制循环;break→找到;left>right→没找到
5
效率特点
时间复杂度 O(log₂n),远超顺序查找的 O(n)。7个元素最多3次比较,100万个元素最多仅20次比较
总结五大要点:第一,前提条件是数组必须有序。第二,三个指针left、right、mid,mid等于(left+right)/2。第三,三分支比较,等于找到break,小于right=mid-1,大于left=mid+1,注意要跳过mid。第四,while(left<=right)控制循环,break说明找到,left>right说明没找到。第五,时间复杂度O(log n),7个元素最多3次比较,100万个元素最多20次比较,效率远超顺序查找。
感谢学习
谢谢!
从折半比较到三指针配合,二分查找的核心你已全部掌握
这节微课就到这里。我们从算法思想、三指针逻辑、范围缩小过程、代码编写到实训案例,完整拆解了二分查找的所有重点和难点。希望大家课后多加练习,熟练掌握二分查找算法。