精通cobol--9.8.2 如何进行二分查找方式

来源:互联网 发布:sql anywhere 10 下载 编辑:程序博客网 时间:2024/04/30 18:35

  二分查找方式最大的特点是从表的中间开始查找,这样往往能大幅提高查找效率。二分查找方式实际上是一种基于算法的高效查找方式。以下结合上面学生成绩管理的例子,先从直观上看看二分查找是如何进行的。

为便于分析,以表中的数据作为例进行讲解。对于表而言,若要查找课程编号为7所对应的课程名称及该学生的分数,通常由以下几步进行。

1)在查找之前,要知道整张表的大小。即对表要有一个通篇的浏览。整张表的数据内容如下:

SUBJECT-CODE

SUBJECT-NAME

MARK

1

Politics

88

2

Math

93

3

Chinese

86

4

English

78

5

Physics

73

6

Chemistry

75

7

Biology

82

8

Geography

85

2)从上表的中间位置开始查找。也就是从数据编号为4的位置查找。比较4和所要查找的编号7的大小,显然74大。由于表中数据编号是顺序编排的,并且为升序,因此编号为4及其以上的编号都比7要小。因此,可以略去编号为4及其以上的半张表不看,只对下半张表进行查找。剩下需要关注的半张表如下:

5

Physics

73

6

Chemistry

75

7

Biology

82

8

Geography

85

3)将剩下的这半张表当作一张新的表,仍然按照上面的方式处理。这样,该表从6以上的半张表又将被略去,剩下的半张表如下:

7

Biology

82

8

Geography

85

4)再将上面的表一分为二。发现上半张表仅剩一条记录,具体如下所示。

7

Biology

82

而这正好就是我们要找的数据。通过该条记录可以知道,课程编号为7所对应的课程名称为Biology,并且该生该门课程的考试分数为82分。

以上具体分析了使用二分查找法是如何查找表中数据的。通过上例可以看到,二分查找实际上就是每次将一张表从中间一分为二。通过将所需查找的数据编号和表正中间的数据编号进行比较,略去不可能存在该数据的半张表。这样,每次查找后,数据都将减少一半,大大提高了查找效率。

需要提到的一点是,对于整张表具有偶数条数据项而言,二分查找所选取的中间为总数据量除以2。比如,上面那张表最初共有8条记录。每次进行查找时所比较的数据编号分别如下。

q      第一次查找将8除以2,得到4。故比较该表中第4条记录,也即编号为4的记录。

q      第二次查找时只剩4条记录。将4除以2,得到2。故比较该表的第2条记录,即编号为6的记录。

q      第三次查找时只剩2条记录。将2除以1,得到1。比较该表的第1条记录,即编号为7的记录。由于正好要求查找编号为7的相关数据,故成功找到,查找结束。

但对于整张表具有奇数条数据项的表而言,将总数据量除以2将得到一个小数。比如若整张表有7条记录,则将7除以2得到3.5,但没有第3.5条记录这么一说。此时,既可以对第3条记录进行比较,也可以对第4条记录进行比较。效果是类似的。具体和那条比较比较,取决于内部的算法。

上面仅从直观上分析了二分查找是如何进行的,并没有说明在机器内部是如何实现的。下面,给出二分查找的伪代码,以了解其算法思想。

以下代码表示在可用于二分查找的表BST中查找数据编号为key的数据。若找到,函数返回该数据在表中的位置,否则返回0。代码如下。

int Search.Binary (BSTable BST, KeyNum key )  

{

low=1;

high=BST.length;

while(low <= high )

{

 mid = (low + high) / 2 ;

 if EQ (key, BST.elem[mid].key)

                 return mid ;

else if   LT(key , ST.elem[mid].key)

                 high = mid – 1 ;

else     low = mid + 1 ;

}

return 0 ;

}

此段代码为伪代码,只用于表示算法过程,并不能实现具体的功能。若要使用COBOL编写该段代码,实现具体的功能,则难度比较大。由于本书是COBOL的入门教材,因此不去深究这个问题。有兴趣的读者朋友可以自己尝试编写。

最后,虽然本书并不要求使用COBOL编写实现二分查找功能的代码,但该算法思想是要掌握的。并且,在后面要讲到的用SEARCH ALL语句查找索引表,正是使用的二分查找方式。

原创粉丝点击