1、二分法查找1、二分查找(Binary Search)二分查找又称折半查找,它是一种效率较高的查找方法。二分查找要求:线性表是有序表,即表中结点按关键字有序,并且要用向量作为表的存储结构。不妨设有序表是递增有序的。2、二分查找的基本思想二分查找的基本思想是:(设 Rlowhigh是当前的查找区间)(1)首先确定该区间的中点位置:(2)然后将待查的 K 值与 Rmid.key 比较:若相等,则查找成功并返回此位置,否则须确定新的查找区间,继续二分查找,具体方法如下:若 Rmid.keyK,则由表的有序性可知 Rmidn.keys 均大于 K,因此若表中存在关键字等于 K 的结点,则该结点必定是在位
2、置 mid 左边的子表 R1mid-1中,故新的查找区间是左子表 R1mid-1。类似地,若 Rmid.keyK)high=mid-1; /继续在 Rlowmid-1中查找elselow=mid+1; /继续在 Rmid+1high中查找return 0; /当 lowhigh 时表示查找区间为空,查找失败 /BinSeareh二分查找算法亦很容易给出其递归程序【参见练习】4、 二分查找算法的执行过程 设算法的输入实例中有序的关键字序列为(05, 13,19,21,37,56,64,75,80,88,92)要查找的关键字 K 分别是 21 和 85。具体查找过程【参见动画演示】5、二分查找判定
3、树二分查找过程可用二叉树来描述:把当前查找区间的中间位置上的结点作为根,左子表和右子表中的结点分别作为根的左子树和右子树。由此得到的二叉树,称为描述二分查找的判定树(Decision Tree) 或比较树(Comparison Tree) 。注意:判定树的形态只与表结点个数 n 相关,而与输入实例中 R1n.keys 的取值无关。【例】具有 11 个结点的有序表可用下图所示的判定树来表示。(1)二分查找判定树的组成圆结点即树中的内部结点。树中圆结点内的数字表示该结点在有序表中的位置。外部结点:圆结点中的所有空指针均用一个虚拟的方形结点来取代,即外部结点。树中某结点 i 与其左( 右) 孩子连接
4、的左(右)分支上的标记“、“)“ 表示:当待查关键字 KRi.key)时,应走左( 右)分支到达 i 的左(右)孩子,将该孩子的关键字进一步和 K 比较。若相等,则查找过程结束返回,否则继续将 K 与树中更下一层的结点比较。(2)二分查找判定树的查找二分查找就是将给定值 K 与二分查找判定树的根结点的关键字进行比较。若相等,成功。否则若小于根结点的关键字,到左子树中查找。若大于根结点的关键字,则到右子树中查找。【例】对于有 11 个结点的表,若查找的结点是表中第 6 个结点,则只需进行一次比较;若查找的结点是表中第 3 或第 9 个结点,则需进行二次比较;找第 1,4 ,7,10 个结点需要比
5、较三次;找到第 2,5,8,11 个结点需要比较四次。由此可见,成功的二分查找过程恰好是走了一条从判定树的根到被查结点的路径,经历比较的关键字次数恰为该结点在树中的层数。若查找失败,则其比较过程是经历了一条从判定树根到某个外部结点的路径,所需的关键字比较次数是该路径上内部结点的总数。【例】待查表的关键字序列为:(05,13,19,21,37,56,64,75,80,88,92),若要查找 K=85 的记录,所经过的内部结点为 6、9、10,最后到达方形结点 “9-10“,其比较次数为3。实际上方形结点中“i-i+1“的含意为被查找值 K 是介于 Ri.key 和 Ri+1.key 之间的,即R
6、i.key#include void TwoInsertSort(int array,int n)int left,right,num;int middle,j,i;for(i = 1;i = left)/ 二分法查找插入位置middle = ( left + right ) / 2; / 指向已排序好的中间位置if( num = left;j- )/ 后移排序码大于 Ri的记录arrayj+1 = arrayj;arrayleft = num;/ 插入int rcmp( const int *a, const int *b)return (*a-*b);void main() int arr
7、ay50;int i;printf(“The original array is :n“);for( i=0; i50; i+ )/数组初始化并显示arrayi = 50-i;printf(“array%d:%dn“, i, arrayi);TwoInsertSort(array,sizeof(array)/sizeof(int);/二分法排序printf(“nAfter sorted :n“);for( i=0; i50; i+ )printf(“array%d:%dn“, i, arrayi);/库函数 bsearch 用二分法查找一个有序数组中的一个特定数,并返回该数的地址a = (int *)bsearch(