parent
de897c9e0e
commit
72dcdc501e
|
@ -1,5 +1,60 @@
|
|||
# 4.3 查找算法
|
||||
|
||||
## 4.3.1 二分查找法
|
||||
## 4.3.1 顺序查找
|
||||
|
||||
## 练习
|
||||
顺序查找是最简单的查找方式,假设有一个长度为 N 的数组,只要从数组的第一个元素开始访问,到最后一个元素结束,中间如果遇到了匹配的值,就返回。
|
||||
|
||||
```cpp
|
||||
/*
|
||||
* @file main.c
|
||||
*/
|
||||
#include <stdio.h>
|
||||
|
||||
#define DATA_SIZE 15
|
||||
|
||||
int main(void)
|
||||
{
|
||||
int i;
|
||||
long find, findidx;
|
||||
long data[DATA_SIZE];
|
||||
|
||||
// 读取数据到 data 的代码
|
||||
...
|
||||
|
||||
// 查找数值为 25 的数据
|
||||
find = 25;
|
||||
findidx = -1;
|
||||
for(i=0; i<DATA_SIZE; i++)
|
||||
{
|
||||
if(find==data[i])
|
||||
{
|
||||
findidx = (long)i;
|
||||
printf("Idx=%d, Val=%d.\n", findidx, data[i]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
最好的情况下,待查找的数据中第一项即为要查找的数据;最坏的情况下,最后一项才是要查找的数据。顺序查找的时间复杂度为 O(N)。
|
||||
|
||||
## 4.3.2 二分查找法
|
||||
|
||||
有没有更好的查找法呢?曾经有个猜商品价格的节目,只要猜对价格这个商品就免费送给参与者,嘉宾每次给出一个价格,主持人会告知是高于真实价格还是低于真实价格。如果我们是参与者,如何更迅速的猜对价格呢?假设商品的价格在 0-100¥ 之间,我们可以先尝试下 50¥;如果价格低了,就试下 75¥;如果高于真实价格就猜 62.5¥...
|
||||
|
||||
每猜一次,价格范围都能够缩小一半,因此很快就能猜到正确的价格。可以使用类似的思路实现查找算法,称之为二分查找法。用二分查找法查找一个数组的方法如下:
|
||||
|
||||
假设数组中有 7 个元素,要查找其中为 'F' 的元素,先从中间的开始找,也就是序号为 3 的元素(6/2=3),也就是 'D'。但是 D<F,因此下次查找 3-6 之间的元素,而 (3+6)/2=4.5,那么我们可以取序号为 4 的元素(向下取整),也可以取序号为 5 的元素(向上取整)。由于向下取整比较容易,因此得到元素 'E',仍然小于 'F',接下来就要查找 4-6 之间的元素,将得到序号为 5 的元素 'F',这就是我们要找的那个。
|
||||
|
||||
| 序号 | 0 | 1 | 2 | 3 | 4 | 5 | 6 |
|
||||
|------|---|---|---|---|---|---|---|
|
||||
| 元素 | A | B | C | D | E | F | G |
|
||||
|
||||
如果使用顺序查找算法,需要进行 6 次比较,而使用二分查找法,只需要 3 次,二分查找法的时间复杂度为 O(logN) (以 2 为底 N 的对数),显然,数组越长越能体现二分查找法的优势。
|
||||
|
||||
二分查找法之所以有效,是因为以上数组是有序数组,在进行查找时,已经知道了数组是从大到小排序还是从小到大排序的。如果数组是无序的,那么很难知道下一个要找的元素所在位置。因此,要进行快速查找,通常需要对数据进行排序,通常排序只需要进行一次,而查找数据是人们会反复进行的操作,因此为了查找而对数据进行排序是非常有意义的。
|
||||
|
||||
## 练习
|
||||
|
||||
某中学级进行了期末考试,学生的姓名、性别、学号(具有唯一性)、年级、班级、成绩都保存在电脑中,实现一个程序,任意给出学号或学生姓名、输出对应的学生信息和数学成绩。
|
Loading…
Reference in New Issue