折半查找算法及程序实现教案
折半查找程序实验报告

1. 理解折半查找(也称为二分查找)的原理和步骤。
2. 掌握在计算机程序中实现折半查找的方法。
3. 通过实验加深对折半查找算法的理解,并提高编程能力。
二、实验环境1. 操作系统:Windows 102. 编程语言:Python3.83. 开发工具:PyCharm三、实验原理折半查找是一种在有序数组中查找特定元素的算法。
其基本思想是将查找区间分为两半,然后判断目标值位于哪一半区间内,再对那一半区间进行同样的操作,直到找到目标值或查找区间为空。
折半查找的步骤如下:1. 初始化两个指针,low指向数组的第一个元素,high指向数组的最后一个元素。
2. 计算中间位置mid = (low + high) / 2。
3. 判断中间位置的元素是否为目标值:a. 如果mid位置的元素等于目标值,则查找成功。
b. 如果mid位置的元素大于目标值,则将high指针减1,继续查找左半区间。
c. 如果mid位置的元素小于目标值,则将low指针加1,继续查找右半区间。
4. 重复步骤2和3,直到找到目标值或low大于high,表示查找失败。
四、实验内容1. 编写一个折半查找的Python程序。
2. 使用该程序对不同的有序数组进行查找操作,并记录查找时间。
3. 分析折半查找算法的性能。
1. 创建一个有序数组。
2. 定义折半查找函数。
3. 调用折半查找函数,并记录查找结果和查找时间。
4. 修改数组,重复步骤3。
5. 分析实验结果。
六、实验代码```pythondef binary_search(arr, target):low = 0high = len(arr) - 1while low <= high:mid = (low + high) // 2if arr[mid] == target:return midelif arr[mid] > target:high = mid - 1else:low = mid + 1return -1# 创建有序数组arr = [1, 3, 5, 7, 9, 11, 13, 15, 17, 19]# 查找目标值target = 7# 调用折半查找函数result = binary_search(arr, target)# 输出查找结果if result != -1:print(f"元素{target}在数组中的位置为:{result}")else:print(f"元素{target}在数组中不存在")```七、实验结果与分析1. 对于不同的有序数组,折半查找函数均能正确地找到目标值或返回-1表示查找失败。
C++二分查找(折半查找)算法实例详解

C++⼆分查找(折半查找)算法实例详解本⽂实例讲述了C++⼆分查找(折半查找)算法。
分享给⼤家供⼤家参考,具体如下:⼆分查找⼜称折半查找,优点是⽐较次数少,查找速度快,平均性能好;其缺点是要求待查表为有序表,且插⼊删除困难。
因此,折半查找⽅法适⽤于不经常变动⽽查找频繁的有序列表。
⼆分查找思想⾸先,假设表中元素是按升序排列,将表中间位置记录的关键字与查找关键字⽐较,如果两者相等,则查找成功;否则利⽤中间位置记录将表分成前、后两个⼦表,如果中间位置记录的关键字⼤于查找关键字,则进⼀步查找前⼀⼦表,否则进⼀步查找后⼀⼦表。
重复以上过程,直到找到满⾜条件的记录,使查找成功,或直到⼦表不存在为⽌,此时查找不成功。
基本算法C语⾔实现代码:int binary_search(int arr[], int len, int elem){int low = 0;int high = len - 1;while (low <= high){int mid = (low + high) / 2;if (elem == arr[mid]){ //相等,返回midreturn mid;}else if (elem > arr[mid]){low = mid + 1; //元素⽐区间中间元素⼤,取区间中间元素的下⼀个元素作为新区间起始位置}else{high = mid - 1; //元素⽐区间中间元素⼩,取区间中间元素的上⼀个元素作为新区间结束位置}}return -1;}添加检测是否是已排好序数组的程序实例#include <iostream>using namespace std;int binary_search(int arr[], int len, int elem){int low = 0;int high = len - 1;while (low <= high){int mid = (low + high) / 2;if (elem == arr[mid]){return mid;}else if (elem > arr[mid]){low = mid + 1;}else{high = mid - 1;}}return -1;}//检测是否排好序int is_sorted(int arr[], int len){int sorted = 1;for (int i = 0; i < len - 1; i++){sorted = sorted && arr[i] <= arr[i + 1];}return sorted;}int main(){int arr[] = { 1, 3, 5, 7, 9, 11, 12, 15, 18, 23, 25, 26 }; int len = sizeof(arr) / sizeof(int);int pos;int sorted = is_sorted(arr, len);if (sorted){pos = binary_search(arr, len, 26);cout << "pos = " << pos << endl;}system("pause");}运⾏结果:pos = 11请按任意键继续. . .希望本⽂所述对⼤家C++程序设计有所帮助。
数据结构-折半查找,哈希查找

一、实验目的熟练掌握顺序查找,折半查找和哈希表等算法的程序实现。
二、实验内容1、实现折半查找的算法编写一个程序,输出在顺序表(1,2,3,4,,6,7,8,9,10)中采用折半查找方法查找关键字9的过程要求:输出查找过程中的比较对象和被查找元素的位置。
2、实现哈希表的相关运算算法编写程序实现哈希表的构造过程。
要求:建立关键字序列(16,74,60,43,54,90,46,31,29,88,77)对应的哈希表A[0...12],哈希函数为H(k)=k%p,并采用开放定址法中的线性探测法解决冲突。
输出构造完成后的哈希表。
程序源代码及运行结果(运行结果可以截图,也可以文字描述分析)1#include<stdio.h>#include<stdlib.h>int fun(int a[],int key){int high=9;int low=0;int mid=(high+low)/2;printf("与之相比较的值为:");while(high>=low){if(key==a[mid]){printf("%-2d",a[mid]);printf("\nkey为数组中第%d个元素\n",mid+1);break;}if(key<a[mid]){ printf("%-2d",a[mid]);high=mid-1;mid=(high+low)/2;}if(key>a[mid]){ printf("%-2d",a[mid]);low=mid+1;mid=(high+low)/2;}}}int main(){int a[10]={1,2,3,4,5,6,7,8,9,10};fun(a,9);system("pause");}运行截图:2#include<stdio.h>int main(){int a[11]={16,74,60,43,54,90,46,31,29,88,77};int A[13]={0};int p=11,H;for(int i=0;i<11;i++){H=a[i]%p;while(A[H]!=0){H++;if(H==12){H=0;}}A[H]=a[i];}for(int i=0;i<13;i++){if(A[i]!=0){printf("%d ",A[i]);}}}运行截图三、小结(不少于100字)感觉好像没有真正理解哈希表,折半查找比较好理解,实现起来也比较容易,自己对代码的熟练程度还不够,课后还会多多练习,查找的方式还有很多,课后应该多看书,对每种算法都有一定的了解。
折半查找算法及程序实现教案

折半查找算法及程序实现一、教材分析教学重点:以图示法方式,演示折半查找算法的基本思想。
教学难点:由折半查找算法的思想到程序代码编写的转换,尤其是其中关键性语句的编写是教学中的难点.二、学情分析学生应该已经掌握程序设计的基本思想,掌握赋值语句、选择语句、循环语句的基本用法和VB基本操作,这节课学生可能会遇到的最大问题是:如何归纳总结对分查找解决不同情况问题的一般规律,鉴于此,在教学中要积极引导学生采取分解动作、比较迁移等学习策略。
三、教学目标知识与技能:理解对分查找的概念和特点,通过分步解析获取对分查找的解题结构,初步掌握对分查找算法的程序实现。
过程与方法:通过分析多种不同的可能情况,逐步归纳对分查找的基本思想和方法,确定解题步骤。
情感态度与价值观:通过实践体验科学解题的重要性,增强效率意识和全局观念,感受对分查找算法的魅力,养成始终坚持、不断积累才能获得成功的意志品质。
四、教学策略与手段1、教学线索:游戏引领——-提出对分查找原理-—- 解析对分查找的算法特征---实践解决问题。
2、学习线索:分解问题—-—归纳问题———实践提升,在三个阶段的不断推进中明确对分查找算法,总结规律。
五、教学过程1、新课导入(1)热身:游戏(2分钟)找同学上来找一本上千页电话册里面的一个名字。
(课程导入我写的不是很详细,自己设计哦)(2)教师引导:所以我不希望只有他一个人体验这种方便,我们教室里还有一大帮人,其实这种什么不止用于查找电话铺,还可以运用到实际生活中,教室里有这么多人,坦白说,按学校的老方法一个人一个人的数,对所有老师来说都及其费力,那我们想想,是不是数数2368,这样好点对吗?。
不要小看这种想法,他其实是非常棒的,他能把解决问题的时间缩短一半,因此我们提出了这种算法2、新课:首先我们一起来看一看折半查询算法中的“折半"的含义.师:何为折半呢?生:减半;打一半的折扣.例如,我手里拿着一根绳子,现在我们来进行折半试验,首先拿住绳子的两个端点,然后从中点的位置进行对折,这样绳子就缩短为原来长度一半,然后将一半的绳子继续执行与刚才相同的操作,使得绳子的长度逐渐的缩短,直到绳子长度短得不能再进行折半了。
折半查找和二叉排序树

折半查找和二叉排序树一、实验目的1、掌握查找的特点。
2、掌握折半查找的基本思想及其算法。
3、熟悉二叉排序树的特点,掌握二叉排序树的插入、删除操作。
二、实验内容1、设有关键字序列k={ 5 ,14 ,18 ,21 ,23 ,29 ,31 ,35 },查找key=21和key=25的数据元素。
2、根据关键字序列{45、24、53、12、37、93}构造二叉排序树,并完成插入13删除关键字53和24的操作。
三、实验环境TC或VC++或Java四、实验步骤1、折半查找(1)从键盘输入上述8个整数5 ,14 ,18 ,21 ,23 ,29 ,31 ,35,存放在数组bub[8]中,并输出其值。
(2)从键盘输入21,查找是否存在该数据元素,若存在,则输出该数据元素在表中的位置,否则给出查找失败的信息。
(3)从键盘输入25,查找是否存在该数据元素,若存在,则输出该数据元素在表中位置,否则给出查找失败的信息。
2、二叉排序树(1)二叉排序树存储定义(2)从键盘上输入六个整数45、24、53、12、37、9构造二叉排序树(3)输出其中序遍历结果。
(4)插入数据元素13,输出其中序遍历结果。
(5)删除数据元素24和53,输出其中序遍历结果。
五、问题讨论1、折半查找递归算法该怎么描述?2、二叉排序树中序遍历结果有什么特点?3、在二叉树排序树中插入一个新结点,总是插入到叶结点下面吗?4、在任意一棵非空二叉排序树中,删除某结点后又将其插入,则所得二排序叉树与原二排序叉树相同吗?六、实验报告内容1、实验目的2、实验内容和具体要求3、完成情况和实验记录,实验记录为实验过程中遇到的问题及解决方法4、程序清单5、所输入的数据及相应的运行结果6、问题回答7、实验心得实验代码:#include<stdio.h>#include<stdlib.h>typedef struct BiTNode{int data;struct BiTNode *lchild,*rchild;}BiTNode,*BiTree;int bub[100];void menu(){printf("********主目录*******\n");printf(" 折半或顺序查找1\n");printf(" 二叉排序树2\n");printf(" 结束程序0\n");printf("*********************\n");}void menu1(){printf("*******目录①*******\n");printf(" 输出元素1\n");printf(" 顺序查找2\n");printf(" 折半查找3\n");printf(" 结束此查找0\n");printf("********************\n");}void menu2(){printf("**********目录②*********\n");printf("输出树的中序遍历结果1\n");printf(" 插入数据元素2\n");printf(" 删除数据元素3\n");printf(" 结束二叉排序0\n");printf("*************************\n"); }void Search(){int i,m,n,key,k;printf("输入元素个数:");scanf("%d",&m);printf("依次输入元素:");for(i=1;i<=m;i++){scanf("%d",&bub[i]);}printf("输入关键字:");scanf("%d",&key);bub[0] = key;do{menu1();printf("选择查找方式:");scanf("%d",&n);switch(n){case 1:for(i=1;i<=m;i++){printf("%d,",bub[i]);}printf("\n");break;case 2:for(i=m;i>=0;i--){if(bub[i]==key){if(i!=0){printf("查找的数据元素在第%d位!\n",i);break;}else{printf("查找失败\n");}}}break;case 3:k = Search_Bin(m,key);if(k!=0)printf("查找的数据元素在第%d位!\n",k);elseprintf("查找失败\n");break;case 0:printf("查找结束\n");break;default:printf("选择错误\n");}}while(n!=0);}int Search_Bin(int m,int key){int low,high,mid;low = 1;high = m;while(low<=high){mid = (low+high)/2;if(key==bub[mid])return mid;else if(key<bub[mid])high = mid-1;elselow = mid+1;}return 0;}BiTree Insert(){BiTree T=NULL,q=NULL,p=NULL;int m;printf("输入数据(-10000停止输入):");scanf("%d",&m);while(m!=-10000){q = (BiTree)malloc(sizeof(BiTNode));q->data = m;q->lchild = q->rchild=NULL;if(!T)T = q;else{p = T;while(1){if(m<p->data){if(p->lchild==NULL){p->lchild = q;break;}p = p->lchild;}else{if(p->rchild==NULL){p->rchild = q;break;}p = p->rchild;}}}scanf("%d",&m);}return T;}void Inorder(BiTree T){if(T){Inorder(T->lchild);printf("%d,",T->data);Inorder(T->rchild);}}int Search_CH(BiTree T,int elem,BiTree f,BiTree *p) {if(!T){*p = f;return 0;}else if(elem==T->data){*p = T;return 1;}else if(elem<T->data)Search_CH(T->lchild,elem,T,p);elseSearch_CH(T->rchild,elem,T,p);}BiTree InsertBST(BiTree T,int elem){BiTree p=NULL,s=NULL;if(!Search_CH(T,elem,NULL,&p)){s = (BiTree)malloc(sizeof(BiTNode));s->data = elem;s->lchild = s->rchild = NULL;if(!p)T = s;else if(elem<p->data)p->lchild = s;elsep->rchild = s;printf("插入成功\n");return T;}printf("输入已有元素,插入失败\n");return T;}BiTree Delete(BiTree T,int elem){BiTree p=NULL,q=NULL,f=NULL,s=NULL;p = T;while(p){if(elem == p->data)break;q = p;if(elem <p->data)p = p->lchild;elsep = p->rchild;}if(!p)printf("查找失败,删除失败\n");return T;}if(!(p->lchild)){if(!q)T = p->rchild;else if(q->lchild == p)q->lchild = p->rchild;elseq->rchild = p->rchild;free(p);}else{f = p;s = p->lchild;while(s->rchild){f = s;s = s->rchild;}if(f==p)f->lchild = s->lchild;elsef->rchild = s->lchild;p->data = s->data;free(s);}printf("删除成功\n");return T;}void ErChaPaiXu(){BiTree T;int m,key;T = Insert();domenu2();printf("输入你的选择:");scanf("%d",&m);switch(m){case 1:printf("中序遍历结果为:");Inorder(T);printf("\n");break;case 2:printf("输入要插入的元素:");scanf("%d",&key);T = InsertBST(T,key);break;case 3:printf("输入要删除的元素:");scanf("%d",&key);T = Delete(T,key);break;case 0:printf("结束二叉排序\n");break;default:printf("输入错误\n");}}while(m!=0);}void main(){int m;do{menu();printf("输入你的选择:");scanf("%d",&m);switch(m){case 1:Search();break;case 2:ErChaPaiXu();break;case 0:printf("程序已结束\n");break;default:printf("输入错误\n");}}while(m!=0);}。
Python查找算法之折半查找算法的实现

Python查找算法之折半查找算法的实现⼀、折半查找算法折半查找算法⼜称为⼆分查找算法,折半查找算法是将数据分割成两等份,⾸先⽤键值(要查找的数据)与中间值进⾏⽐较。
如果键值⼩于中间值,可确定要查找的键值在前半段;如果键值⼤于中间值,可确定要查找的键值在后半段。
然后对前半段(后半段)进⾏分割,将其分成两等份,再对⽐键值。
如此循环⽐较、分割,直到找到数据或者确定数据不存在为⽌。
折半查找的缺点是只适⽤于已经初步排序好的数列;优点是查找速度快。
⽣活中也有类似于折半查找的例⼦,例如,猜数字游戏。
在游戏开始之前,⾸先会给出⼀定的数字范围(例如0~100),并在这个范围内选择⼀个数字作为需要被猜的数字。
然后让⽤户去猜,并根据⽤户猜的数字给出提⽰(如猜⼤了或猜⼩了)。
⽤户通常的做法就是先在⼤范围内随意说⼀个数字,然后提⽰猜⼤了/猜⼩了,这样就缩⼩了猜数字的范围,慢慢地就猜到了正确的数字,如下图所⽰。
这种做法与折半查找法类似,都是通过不断缩⼩数字范围来确定数字,如果每次猜的范围值都是区间的中间值,就是折半查找算法了。
例如,已经有排序好的数列:12、45、56、66、77、80、97、101、120,要查找的数据是 101,⽤折半查找步骤如下:步骤1:将数据列出来并找到中间值 77,将 101 与 77 进⾏⽐较,如下图所⽰。
步骤2:将 101 与 77 进⾏⽐较,结果是 101 ⼤于 77,说明要查找的数据在数列的右半段。
此时不考虑左半段的数据,对在右半段的数据再进⾏分割,找中间值。
这次中间值的位置在 97 和 101之间,取 97,将 101 与 97 进⾏⽐较,如下图所⽰。
步骤3:将 101 与 97 进⾏⽐较,结果是 101 ⼤于 97,说明要查找的数据在右半段数列中,此时不考虑左半段的数据,再对剩下的数列分割,找中间值,这次中间值位置是 101,将 101 与 101进⾏⽐较,如下图所⽰。
步骤4:将 101 与 101 进⾏⽐较,所得结果相等,查找完成。
编程实现折半查找算法。

编程实现折半查找算法。
中括号内的内容为主题:编程实现折半查找算法一、介绍折半查找算法,也被称为二分查找算法,是一种高效的查找算法。
它可以在有序的数据集合中查找特定元素的位置,其时间复杂度为O(log n)。
本文将带你一步一步了解并编程实现折半查找算法。
二、算法思想1. 确定查找区间的起始和结束位置。
2. 计算区间的中间位置。
3. 如果中间位置的元素等于目标元素,则查找成功返回该位置。
4. 如果中间位置的元素大于目标元素,则在前半部分继续查找。
5. 如果中间位置的元素小于目标元素,则在后半部分继续查找。
6. 重复步骤2-5,直到找到目标元素或者区间为空。
三、代码实现下面是使用Python语言实现折半查找算法的代码:pythondef binary_search(arr, target):low = 0high = len(arr) - 1while low <= high:mid = (low + high) 2guess = arr[mid]if guess == target:return midelif guess > target:high = mid - 1else:low = mid + 1return -1代码说明:1. 函数`binary_search`接受一个有序数组`arr`和目标元素`target`作为参数。
2. 初始化变量`low`为区间左端的索引,`high`为区间右端的索引。
3. 使用`while`循环在区间内进行查找,直到找到目标元素或者区间为空。
4. 计算区间的中间位置`mid`,并将该位置的元素赋值给变量`guess`。
5. 比较`guess`和`target`的大小,如果相等,则查找成功返回`mid`。
6. 如果`guess`大于`target`,则目标元素在前半部分,将`high`更新为`mid - 1`。
7. 如果`guess`小于`target`,则目标元素在后半部分,将`low`更新为`mid + 1`。
折半查找

深圳大学实验报告课程名称:数据结构实验与课程设计实验项目名称:顺序查找、折半查找实验学院:计算机与软件学院专业:指导教师:杨芳报告人:张健哲学号:2013150372 班级:8 实验时间:2014/11/27实验报告提交时间:2014/11/27教务处制一、实验目的1、掌握顺序查找、折半查找算法的基本思想2、掌握顺序查找、折半查找算法的实现方法3、掌握顺序查找、折半查找的时间性能二、实验要求1、熟悉C++语言编程2、了解顺序查找、折半查找的原理三、实验内容本次实验有两项必做内容和一项选作内容:(一)顺序查找实验1、问题描述给出一个队列和要查找的数值,找出数值在队列中的位置,队列位置从1开始,要求使用带哨兵的顺序查找算法2、顺序查找算法⑴、在表的第0位置,赋给定值Key⑵、从表中最后一个记录开始⑶、逐个进行记录的关键字和给定值Key的比较⑷、若某个记录比较相等,则查找成功⑸、若直到第1个记录都比较不等,则查找不成功3、输入第一行输入n,表示队列有n个数据第二行输入n个数据,都是正整数,用空格隔开第三行输入t,表示有t个要查找的数值第四行起,输入t个数值,输入t行4、输入样本833 66 22 88 11 27 44 5532211995、输出每行输出一个要查找的数值在队列的位置,如果查找不成功,输出字符串error6、输出样本35error(二)折半查找实验1、问题描述在一个有序序列中,折半查找一个关键字;返回查找是否成功,如果成功,输入关键字所在的位置和查找次数。
2、查找算法⑴、n个对象从小到大存放在有序顺序表BinList中,Key为给定值⑵、设low、high指向待查元素所在区间的下界、上界,即low=1, high=BinListLen⑶、设mid指向待查区间的中点,即⑷、让Key与mid指向的记录关键字比较若Key=BinList[mid],查找成功,结束若Key<BinList[mid],则high=mid-1 [上半区间]若Key>BinList[mid],则low=mid+1 [下半区间]⑸、重复⑶、⑷操作,直至low>high时,查找失败。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
折半查找算法及程序实现
一、教材分析
教学重点:以图示法方式,演示折半查找算法的基本思想。
教学难点:由折半查找算法的思想到程序代码编写的转换,尤其是其中关键性语句的编写是教学中的难点。
二、学情分析
学生应该已经掌握程序设计的基本思想,掌握赋值语句、选择语句、循环语句的基本用法和VB基本操作,这节课学生可能会遇到的最大问题是:如何归纳总结对分查找解决不同情况问题的一般规律,鉴于此,在教学中要积极引导学生采取分解动作、比较迁移等学习策略。
三、教学目标
知识与技能:理解对分查找的概念和特点,通过分步解析获取对分查找的解题结构,初步掌握对分查找算法的程序实现。
过程与方法:通过分析多种不同的可能情况,逐步归纳对分查找的基本思想和方法,确定解题步骤。
情感态度与价值观:通过实践体验科学解题的重要性,增强效率意识和全局观念,感受对分查找算法的魅力,养成始终坚持、不断积累才能获得成功的意志品质。
四、教学策略与手段
1、教学线索:游戏引领---提出对分查找原理--- 解析对分查找的算法特征---实践解决问题。
2、学习线索:分解问题---归纳问题---实践提升,在三个阶段的不断推进中明确对分查找算法,总结规律。
五、教学过程
1、新课导入
(1)热身:游戏(2分钟)
找同学上来找一本上千页电话册里面的一个名字。
(课程导入我写的不是很详细,自己设计哦)
(2)教师引导:所以我不希望只有他一个人体验这种方便,我们教室里还有一大帮人,其实这种什么不止用于查找电话铺,还可以运用到实际生活中,教室里有这么多人,坦白说,按学校的老方法一个人一个人的数,对所有老师来说都及其费力,那我们想想,是不是数数2368,这样好点对吗?。
不要小看这种想法,他其实是非常棒的,他能把解决问题的时间缩短一半,因此我们提出了这种算法
2、新课:
首先我们一起来看一看折半查询算法中的“折半”的含义。
师:何为折半呢?
生:减半;打一半的折扣。
例如,我手里拿着一根绳子,现在我们来进行折半试验,首先拿住绳子的两个端点,
然后从中点的位置进行对折,这样绳子就缩短为原来长度一半,然后将一半的绳子继续执行与刚才相同的操作,使得绳子的长度逐渐的缩短,直到绳子长度短得不能再进行折半了。
师:那什么时候就不能再折半了呢?
生:即绳子的两个端点合二为一为止。
折半查找算法的思想与绳子折半的过程基本相同。
下面我们先通过图示来看看折半查找算法究竟是什么?
教学步骤二:分解对分查找算法(5分钟)
假设一个从小到大排列的数据存放在一个数组中——Data(10),而查找数据存放在变量x 中。
如图1所示,橙色方框的代表的是查询数据x ,每个浅兰色方框代表的是数组中的每个元素,框内显示的数据是每个数组元素对应的下标(序号),整排的浅兰色方框就可以看成整个数组,即待查数据表(数组元素表)。
图一
第一步:就像抓住绳子的两端一样,首先设立两个标记Low 、High 分别来标识查询区间的低端和高端,即数组元素的下标,如图1所示。
师:对于初始查询区间,它们是多少呢?
生:Low=0 , High=10
第二步:取区间的中点标记Mid ,如图2所示。
师:查询区间的中点为多少?(这个地方,有的学生可能直接说出下标值,所以要提醒学生让中点和两个端点相联系,即用端点表示中点)
生:Mid=(Low+High)/2
师:中点位置上的数据为什么?(提醒学生数据是放在数组Data 中的) 生:
Data( Mid)
Low High
第三步:判断中点位置上的数据Data( Mid)与要查找数x 是否相等,
如何相等,则找到,并结束查找;如果不相等,就执行第四步。
师:这个判断语句如何写呢?
生:if Data( Mid)=x then
print “x 找到”
结束查找
end if
第四步:如果不相等,那么对查询区间进行折半操作。
师:那如何折半——是从中点处向左侧折半还是向右侧折半?(这是整个折半查询进行下去的关键所在,所以一定要让学生自己学会判断)
由于待找数据表是从小到大排列的,而且区间中点位置上的数据Date(Mid)也知道,所以,通过Data(Mid)与x 的比较,看一看,x 比Data(Mid)大还是小,就可以判断出x 落在中间数Data(Mid)的左侧还是右侧,从而判断出向左还是向右折半。
师:那么,判断语句如何写呢?
生:if Data(Mid)<x then
说明x 比Data(Mid)大,且数据表是从小到大排列的,从而判断出x 落在右侧。
所以从中点处向右侧折半。
师:如图3所示,观察新查询区间,发现高端标记没有变化,而低端标记变了,那低端标记Low 为多少呢?
生:我们来看图2,由于中点位置上的数据已经被查询过,所以,新查询区间内的数据就不能再包含它,Low 就得比Mid 多1,即:Low=Mid+1。
Mid
Low High
e
lse
说明x 比Data(Mid)小,所以就向左侧折半,如图4所示,观察新区间,发现低端标记没有变化,而高端标记变了,同样道理,新查询区间内不能包含Mid 对应的数据,所有High 比Mid 小1,即:High=Mid –1
end if
第五步:重复执行第二、三、四步骤。
师:如果一直没有找到,那么什么时候不再进行折半查找呢?(提示学生想一想绳子折半的情况)
生:直至Low>High ,停止折半查询。
教学步骤四:对各种情况进行归纳总结。
(1)x 与data(mid)的大小比较影响i,j 的取值的规律:
i 的取值规律:if data(mid)<x then low=mid+1
j 的取值规律:if data(mid)>x then high=mid-1
用分支结构实现。
(2)继续进行重复查找的条件: low ≤high ,用循环结构实现。
教学步骤五:构建对分查找的流程图
Low
High
Low High
教师事先设计好Vb窗体,学生只需要在相应的程序体输入代表算法思想的
关键语句。
附主要程序体:
Private Sub Command2_Click()
Dim x As Integer, mid As Integer, low As Integer, high As Integer x = Val(Text1.Text)
low = 0: high = 10
Do While low <= high
mid = (low + high) \ 2
If data(mid) = x Then
Text2.Text = "找到了,是第" & mid & "个"
Exit Sub
End If
If data(mid) < x Then
low = mid + 1
Else
high = mid - 1
End If
Loop
Text2.Text = "找不到"
End Sub
程序说明:1、获得要查找的数据x的值 x = Val(Text1.Text)
2、i,j赋初值。
low = 1: high = 10
3、求mid的值。
mid = (low + high) \ 2
4、分三种情况,(1)如果x=data(mid),则如果 data(mid) = x 那么
Text2.Text = "找到了,在第" + Str(mid) + "个"。
(2)如果x>data(mid),那么low=mid+1 否则 high=mid+1
5、重复上述的3,4步,直到low超出j(或者理解为low<=high不成立,所以不能用for next,而要用do while语句)
6、如果有找到x,那执行第4步(1)步后应该输出找到的位置后退出程序,如果不退出,说明x没有找到,所以在相应位置要输出“找不到”。
折半查找算法基本思想总结(2分钟)
对一有序数据表,首先从初始查找区间开始,取出区间中点位置上的数据与要查询数据进行比较,若相等,则查找成功,并结束查询;否则,将当前查找区间缩小一半。
在新的查询区间内,同样取出区间中点位置上的数据与要查询数据进行比较,若相等,则查询成功,并结束查询,否则将新的查询区间再次缩小一半。
然后继续采用相同的方法,直到查找数据成功或者查询区间不能再折半(即查询失败)为止
教学步骤七:评价。
评价学生的程序实现情况,并讨论或实践问题:如果是降序序列,该怎么样改动程序?如果序列元素不是10个,而是100个或更多呢?
教学步骤八:总结提升。
(1)由于对分查找过程中的每次比较都能使得搜索空间减半,对分查找将不会使用超过log2n次比较来找到目标值。
(2)提升对分查找算法的实际意义:同学们可能还没有意识到二分查找是多么高效,那不妨设想一下在一个包含一百万个人名的电话簿中找一个名字,二分查找可以让你不超过21次就能找到指定的名字。
如果你能够将世界上所有的人按照姓名排序,那么你可以在35步以内找到任何人。
八、作业:
1、以下的三组元素序列能采用对分查找法来查找吗?
(1) 19,33,35,53,56,67,78,99
(2)53,35,67,78,56,99,33,19
(3)99,67,56,45,33,10,9,1,0,-9
2、设计一个能用对分查找算法思想解决的实际问题。