完善查找算法内容

Signed-off-by: lion187 <cy187lion@sina.com>
This commit is contained in:
lion187 2018-12-21 22:46:06 +08:00
parent de897c9e0e
commit 72dcdc501e
1 changed files with 57 additions and 2 deletions

View File

@ -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 的对数),显然,数组越长越能体现二分查找法的优势。
二分查找法之所以有效,是因为以上数组是有序数组,在进行查找时,已经知道了数组是从大到小排序还是从小到大排序的。如果数组是无序的,那么很难知道下一个要找的元素所在位置。因此,要进行快速查找,通常需要对数据进行排序,通常排序只需要进行一次,而查找数据是人们会反复进行的操作,因此为了查找而对数据进行排序是非常有意义的。
## 练习
某中学级进行了期末考试,学生的姓名、性别、学号(具有唯一性)、年级、班级、成绩都保存在电脑中,实现一个程序,任意给出学号或学生姓名、输出对应的学生信息和数学成绩。