折半查找法PPT课件
.
high=13
2
例:查找值为22的记录的过程:
0 1 2 3 4 5 6 7 8 9 10 11 12 13
7 14 18 21 23 29 31 35 38 42 46 49 52
low=1 18<22 mid=7 31>22 mid=3 high=6
low=4 mid=5 23>22
high=4 21<22
9.2.2 折半查找(二分查找)
适用条件:
➢线性表中的记录必须按关键码有序; ➢必须采用顺序存储。
基本思想:在有序表中,取中间记录作为比较对象
,若给定值与中间记录的关键码相等,则查找成功; 若给定值小于中间记录的关键码,则在中间记录的左 半区继续查找;若给定值大于中间记录的关键码,则 在中间记录的右半区继续查找。不断重复上述过程, 直到查找成功,或所查找的区域无记录,查找失败。
mid=4 low=5 low>high
.
high=13
3
折半查找——非递归算法
int BinSearch1(int r[ ], int n, int k) //数组r[1] ~ r[n]存放查找集合 {
low=1; high=n; while (low<=high) {
mid=(low+high)/2; if (k<r[mid]) high=mid-1; else if (k>r[mid]) low=mid+1;
的二叉树为折半查找判定树,简称判定树。
.
6
判定树的构造方法
⑴ 当n=0时,折半查找判定树为空;
⑵ 当n>0时,折半查找判定树的根结点是有序表中序 号为mid=(n+1)/2的记录,根结点的左子树是与有序 表r[1] ~ r[mid-1]相对应的折半查找判定树,根结点的 右子树是与r[mid+1] ~ r[n]相对应的折半查找判定树。
.
1
例:查找值为14的记录的过程:
0 1 2 3 4 5 6 7 8 9 10 11 12 13
7 14 18 21 23 29 31 35 38 42 46 49 52
low=1 14<18 mid=7 14<31 mid=3 high=6
high=2 mid=1 14>7
low=2
mid=2 14=14
查找判定树中从根结点到该记录结点的路径,和给定
值的比较次数等于该记录结点在树中的层数。
查找不成功:查找失败的过程就是走了一条从根结
点到外部结点的路径,和给定值进行的关键码的比 较次数等于该路径上内部结点的个数。
.
9
return BinSearch2(r, low, mid-1, k); else if (k>r[mid])
return BinSearch2(r, mid+1, high, k); else return mid; } }
.
5
折半查找判定树
判定树:折半查找的过程可以用二叉树来描述,树
中的每个结点对应有序表中的一个记录,结点的值为 该记录在表中的位置。通常称这个描述折半查找过程
else return mid; } return 0; }
.
4
折半查找——递归算法
int BinSearch2(int r[ ], int low, int high, int k) //数组r[1] ~ r[n]存放查找集合 {
if (low>high) return 0; else {
mid=(low+high)/2; if (k<r[mid])
.
7
判定树的构造方法(例:11个结点的判定树)
1
-1
6
3 4
2 3-4
9
7
10
5 6-7 8 9-10
11
1-2 2-3 4-5 5-6 7-8 8-9 10-11 11-
内部结点
外部结点
.
8
折半查找性能分析
具有n个结点的折半查找判定树的深度为 log 2 n +1 。
查找成功:在表中查找任一记录的过程,即是折半
折半查找法
二分查找是在我们整个数据结构当中一个比较重要的算法,它的思想在我们的实际开发过程当中应用得非常广泛。
在实际应用中,有些数据序列是已经经过排序的,或者可以将数据进行排序,排序后的数据我们可以通过某种高效的查找方式来进行查找,今天要讲的就是折半查找法(二分查找),它的时间复杂度为O(logn),将以下几个方面进行概述了解二分查找的原理与思想分析二分查找的时间复杂度掌握二分查找的实现方法了解二分查找的使用条件和场景1 二分查找的原理与思想在上一个章节当中,我们学习了各种各样的排序的算法,接下来我们就讲解一下针对有序集合的查找的算法—二分查找(Binary Search、折半查找)算法,二分查找呢,是一种非常容易懂的查找算法,它的思想在我们的生活中随处可见,比如说:同学聚会的时候喜欢玩一个游戏——猜数字游戏,比如在1-100以内的数字,让别人来猜从,猜的过程当中会被提示是猜大了还是猜小了,直到猜中为止。
这个过程其实就是二分查找的思想的体现,这是个生活中的例子,在我们现实开发过程当中也有很多应用到二分查找思想的场景。
比如说仙现在有10个订单,它的金额分别是6、12 、15、19、24、26、29、35、46、67 请从中找出订单金额为15的订单,利用二分查找的思想,那我们每一次都会与中间的数据进行比较来缩小我们查找的范围,下面这幅图代表了查找的过程,其中low,high代表了待查找的区间的下标范围,mid表示待查找区间中间元素的下标(如果范围区间是偶数个导致中间的数有两个就选择较小的那个)第一次二分查找第二次二分查找第三次二分查找通过这个查找过程我们可以对二分查找的思想做一个汇总:二分查找针对的是一个有序的数据集合,查找思想有点类似于分治思想。
每次都通过跟区间的中间元素对比,将待查找的区间范围缩小为原来的一半,直到找到要查找的元素,或者区间被缩小为0。
一:查找的数据有序二:每次查找,数据的范围都在缩小,直到找到或找不到为止。
二分查找、三分搜索
#include <iostream> #include <algorithm> #include <map> #include <set> #include <ctime> #include <cmath> #include <string> #include <list> using namespace std;
while (l + EPS < r) //EPs 要求的精度 { //mid 和midmid的具体公式无所谓 //只要mid在midmid的右边,能满足精度要求即可 mid = (l + r) / 2; midmid = (mid + r) / 2; mid_value = Calc(mid); midmid_value = Calc(midmid); // 假设求解极小值
二分查找、三分搜索
蔡尚真 609787
二分查找
二分查找又称折半查找,优点是比较次数 少,查找速度快,平均性能好;其缺点是 要求待查表为有序表,且插入删除困难。 因此,折半查找方法适用于不经常变动而 查找频繁的有序列表。
二分查找
1.二分查找的时间复杂度是O(log(n)),最坏情况下的时间复 杂度是O(n)。 2.二分查找的一个条件是待查询的数组是有序的,我们假设 这里的数组是升序的。 3.二分查找的主要思路就是设定两个指针start和end分别指 向数组元素的首尾两端,然后比较数组中间结点arry[mid]和 待查找元素。如果待查找元素小于中间元素,那么表明待 查找元素在数组的前半段,那么将end=mid-1,如果待查找 元素大于中间元素,那么表明该元素在数组的后半段,将 start=mid+1;如果中间元素等于待查找元素,那么返回mid的 值。
第7章查找分析
2020年10月29日
折半查找(非递归算法)
int Search_Bin ( SSTable ST , KeyType key) {
low = 1; high = ST.length; while ( low <= high ) { mid = ( low + high ) / 2 ;
找21
7 8 9 10 11 7 5 13 19 21 37 56 64
high
8 9 10 11 75 80 88 92
low
mid
high
1 2 3 4 5 6 7 8 9 10 11
5 13 19 21 37 56 64 75 80 88 92
typedef struct{
KeyType key; InfoType otherinfo;
}ElemType;
顺序表的定义:
typedef struct { ElemType *R; //表基址 int length; //表长
}SSTable;
2020年10月29日
第2章在顺序表L中查找值为e的数据元素
1 2 3 4 5 6 7 8 9 10 11 5 13 19 21 37 56 64 75 80 88 92
low high mid
1 2 3 4 5 6 7 8 9 10 11 5 13 19 21 37 56 64 75 80 88 92
high low
2020年10月29日
折半查找(非递归算法)
第7章 查找
2020年10月29日
2020年10月29日
第7章 查找
教学内容
7.1 查找的基本概念 7.2 线性表的查找 7.3 树表的查找 7.4 哈希表的查找
计算机数据结构知识点梳理 顺序查找法、折半查找法
typedef struct node{ int A[m];
//每个结点含有m个整数,本例m为5 struct node *next;
}LNode, *LinkList; typedef struct{
int j; //正整数在结点内的序号 LNode *s; //结点的指针 }rcd;
}
[题2]顺序存储的某线性表共有123个元素,按分块查找的要求等分为3块。若对索引 表采用顺序查找方法来确定子块,且在确定的子块中也采用顺序查找方法,则在等 概率的情况下,分块查找成功的平均查找长度为( )。
A.21
B. 23
C. 41
D. 62
分析:分块查找成功的平均查找长度为ASL=(s2+s+n)/2s。在本题中,n=123, s=123/3=41,故平均查找长度为23。
对表中每个数据元素的查找过程,可用二叉树来描述,称这个描述折半查找过 程的二叉树为判定树,表的中间结点是二叉树的根,左子表相当于左子树, 右子表相当于右子树。折半查找的过程是从根结点到待查找结点的过程,不 论查找成功或失败,查找长度均不超过树的高度,因此,如果有序表的长度 为n,那么在查找成功时与给定值进行比较的关键字个数至多为[㏒2n] +1。
4 、分块查找法
分块查找法要求将列表组织成以下索引顺序结构: (1)首先将列表分成若干个块(子表)。一般情况下,块的长度均匀, 最后一块 可以不满。每块中元素任意排列,即块内无序,但块与块之间有序。 (2)构造一个索引表。其中每个索引项对应一个块并记录每块的起始位置,以及每 块中的最大关键字(或最小关键字)。索引表按关键字有序排列。
假定将长度为n的表分成b块,且每块含s个元素,则b=n/s。又假定表中每个元素的查 找概率相等,则每个索引项的查找概率为1/b,块中每个元素的查找概率为1/s。
二分法查找教学教材
0
1
2
3
4
5
6
7
8
9
10
11
9
13
15
30
37
55
60
75
80
90
92
low
high
mid
r表
例2:查找k=85的过程:
失败:下界low> 上界high,说明表中没有关键字值等于85的记录。
(图2:查找k=85的示意图)
四、பைடு நூலகம்法实现
1、结点结构类型定义:(假设只有key域) struct element { int key; }; 2、查找表存储结构定义: #define MAXITEM 100 typedef struct element sqlist[MAXITEM];
low=mid+1;
high=mid-1;
low<=high
/*有效的查找范围*/
/*在右半部分查找/ *
/*在左半部分查找*/
五. 程序实现
运行程序: 验证二分法查找函数的功能.
课 后 作 业
1、编写一程序: 完成班级学生的信息顺序存储,在该信息表上用二分法查找学号为20和15的学生信息,成功输出该记录的值,不成功显示“该生不存在”的信息。 2、预习:二叉判定树及二分法查找算法性能分析
二、基本思想
每次将给定值k与有序表中间位置上的记录关键字进行比较,确定待查记录所在的范围,然后逐步缩小查找范围,直到确定找到或找不到对应记录为止。
三、查找过程
1、注意:设有序表记录按关键字升序排列。 2、设置整型变量 :指示查找范围的下界 :指示查找范围的上界 :指示中间记录所在的位置,
折半查找法的两种实现形式
折半查找法的两种实现折半查找法:在有序表中,把待查找数据值与查找范围的中间元素值进行比较,会有三种情况出现:1)待查找数据值与中间元素值正好相等,则放回中间元素值的索引。
2)待查找数据值比中间元素值小,则以整个查找范围的前半部分作为新的查找范围,执行1),知道找到相等的值。
3)待查找数据值比中间元素值大,则以整个查找范围的后半部分作为新的查找范围,执行1),知道找到相等的值4)如果最后找不到相等的值,则返回错误提示信息。
按照二叉树来理解:中间值为二叉树的根,前半部分为左子树,后半部分为右子树。
折半查找法的查找次数正好为该值所在的层数。
等概率情况下,约为log2(n+1)-1//Data为要查找的数组,x为待查找数据值,beg为查找范围起始,last 为查找范围终止//非递归法int BiSearch(int data[], const int x, int beg, int last) {int mid;//中间位置if (beg > last){return -1;}while(beg <= last){mid = (beg + last) / 2;if (x == data[mid] ){return mid;}else if (data[mid] < x){beg = mid + 1;}else if (data[mid] > x){last = mid - 1;}}return -1;}//递归法int IterBiSearch(int data[], const int x, int beg, int last){int mid = -1;mid = (beg + last) / 2;if (x == data[mid]){return mid;}else if (x < data[mid]){return IterBiSearch(data, x, beg, mid - 1);}else if (x > data[mid]){return IterBiSearch(data, x, mid + 1, last);}return -1;}//主函数int _tmain(int argc, _TCHAR* argv[]){int data1[60] = {0};int no2search = 45;cout << "The array is : " << endl;int siz = sizeof(data1)/sizeof(int);for (int i = 0; i < siz; i++){data1[i] = i;cout << data1[i] << " ";}cout << endl;int index = -1;//index = BiSearch(data1, no2search, 0, siz);index = IterBiSearch(data1, no2search, 0, siz);cout << "Index of " << no2search << " is " << index << endl;getchar();return 0;}。
《折半查找法》课件
在数据库、搜索引擎、物流配送 等领域,快速准确的查找是实现 高效服务的关键。
折半查找法的概念
• 定义:折半查找法,又称二分查找法,是一种在有序数组中查 找某一特定元素的搜索算法。搜索过程从数组的中间元素开始 ,如果中间元素正好是要查找的元素,则搜索过程结束;如果 某一特定元素大于或者小于中间元素,则在数组大于或小于中 间元素的那一半中查找,而且跟开始一样从中间元素开始比较 。如果在某一步骤数组为空,则代表找不到。这种搜索算法每 一次比较都使搜索范围缩小一半。
感谢观看
与线性查找法相比,折半查找 法在数据量大的情况下具有明 显优势。
需要快速查找的场景
在某些对时间要求较高的场景中 ,如实时交易系统、在线游戏等
,需要快速查找数据。
折半查找法能够在较短时间内找 到目标数据,满足快速查找的需
求。
与其他查找算法相比,折半查找 法具有较高的查找速度。
二分搜索的应用场景
二分搜索是折半查找法的另一种表述方式,适用于有序数组的查找。
线性二分查找的变种
在有序数组中,从中间元素开始,如果中间元素正好是目标值,则搜索过程结束;如果目标值大于或 小于中间元素,则在数组大于或小于中间元素的那一半中查找,但这一次从那一半的起始位置开始比 较。
多重二分查找
多重二分查找是指在一次二分查找过程中,对多个有序数组 进行查找的方法。通过将多个有序数组按照某种规则进行组 合,可以大大提高查找效率。
在需要频繁进行查找操作的场景中,如搜索引擎、数据分析等,二分搜索能够提高 查找效率。
二分搜索适用于任何有序数据集,只要能够确定数据集的左边界和右边界即可。
05
折半查找法的优化与改进
二分查找的变种
线性二分查找
折半查找算法的前提是什么.ppt
L.r[0] = L.r[i];
// 复制为监视哨
for ( j=i-1; L.r[0].key < L.r[j].key; -- j ) L.r[j+1] = L.r[j]; // 记录后移
L.r[j+1] = L.r[0]; // 插入到正确位置 }
假设dk=1
} // InsertionSort
例如:初始序列:1,8,9,4,2,7,6
无序
排序之后:1,2,4,6,7,8,9
有序(升序)
2. 排序的目的是什么? ——便于查找!
3.排序算法的好坏如何衡量?
• 时间效率——排序速度(即排序所花费的全部比较次数) • 空间效率——占内存辅助空间的大小 • 稳定性——若两个记录A和B的关键字值相等,但排序后A、
for (k=0; k<t; ++t) ShellInsert(L, dlta[k]); //一趟增量为dlta[k]的插入排序
} // ShellSort
10.3 交换排序
交换排序的基本思想是:两两比较待排序记录的关键 码,如果发生逆序(即排列顺序与排序后的次序正好 相反),则交换之,直到所有记录都排好序为止。
if (L.r[i].key < L.r[i-1].key) {
位置和前面 演示一致吗
L.r[0] = L.r[i];
// 复制为监视哨
for ( j=i-1; L.r[0].key < L.r[j].key; -- j ) L.r[j+1] = L.r[j]; // 记录后移
L.r[j+1] = L.r[0]; // 插入到正确位置 }
随着排序进展dk值逐渐变小子序列中对象个数逐渐变多由于前面工作的基础大多数对象已基本有序值逐渐变小子序列中对象个数逐渐变多由于前面工作的基础大多数对象已基本有序所以排序速度仍然很快
《折半查找法》课件
折半查找法要求数据集合必须是有序的,如果数据无序,则需要先进行排序操作。
折半查找法的实现步骤
1
步骤一
确定查找范围的起始位置和结束位置。
步骤二
2
计算中间元素的索引位置。
3
步骤三
比较目标元素与中间元素的大小关系。
步骤四
4
根据比较结果,确定新的查找范围, 更新起始位置和结束位置。
Code示例解析
通过一个简单的Code示例,演示折半查找法的具体实现过程。包括定义函数,输入数据集合,以及完 成查找。
回答折半查找法常见问题,并给出解决方案,帮助观众更好地理解和应用该 算法。
附录:Code示例详解
对之前提到的Code示例进行详细解析,深入讲解每一行代码的含义和实现思路。
《折半查找法》PPT课件
探索折半查找法——一种高效的查找算法。了解其原理、适用场景和优缺点。 解析实现步骤,演示Code示例,并应用到实际案例中。
什么是折半查找法?
折半查找法,又称二分查找法,是一种高效的查找算法。它基于有序数据集 合,在每一步中将查找范围缩小一半,直至找到目标元素。
折半查找法原理
折半查找法对数据结构的影响
分析折半查找法对数据结构的影响,并讨论如何选择合适的数据结构,以支 持高效的折半查找操作。
其他相关思考
引发观众对折半查找法的思考,如进一步优化算法、应用于其他领域、相关研究方向等。
小结与总结
总结折半查找法的主要内容和关键要点,提醒观众重点掌握和应用的知识点。
未来发展趋势
折半查找法的原理是通过比较目标元素与中间元素的大小关系,来确定应该 继续向左半部分还是向右半部分进行查找,以此类推,直至找到目标元素。
适用场景及优缺点
折半查找法
#include <stdio.h>#include <stdlib.h>#define LIST_SIZE 20typedef int KeyType;typedef int OtherType;typedef struct{KeyType key;OtherType other_data;}RecordType;typedef struct{RecordType r[LIST_SIZE+1]; /* r[0]为工作单元*/int length;}RecordList;void createlist(RecordList *l,KeyType Key[LIST_SIZE],int KeyNum){int i;l->length =KeyNum;for(i=1; i<=KeyNum; i++){l->r[i].key =Key[i-1];}}int BinSrch(RecordList l, KeyType k)/*在有序表l中折半查找其关键字等于k的元素,若找到,则函数值为该元素在表中的位置*/{int low,high,mid;low=1;high=l.length;while(low<=high){mid=(low=high)/2;if(k==l.r[mid].key)return(mid);else{if(k<l.r[mid].key)high=mid-1;elselow=mid=1;}return(0);}}void SortData(RecordList *l){KeyType TempData;for(int i=1; i<l->length; i++)for(int j=i+1; j<=l->length; j++)if(l->r[i].key>l->r[j].key){TempData=l->r[i].key;l->r[i].key=l->r[j].key;l->r[j].key=TempData;TempData=l->r[i].other_data;l->r[i].other_data=l->r[j].other_data;l->r[j].other_data=TempData;}}void Display(RecordList *l){for(int i=1; i<=l->length; i++){printf("%3d ",l->r[i].key);}printf("\n");}void main(){RecordList l;int locate,KeyNum=6;KeyType k,Key[LIST_SIZE]={24,53,90,12,28,45};createlist(&l,Key,KeyNum);printf("排序前输出顺序表:\n");Display(&l);SortData(&l);printf("排序后输出顺序表:\n");Display(&l);printf("请输入要查找的元素:");scanf("%d",&k);locate = BinSrch(l,k);if(locate == 0)printf("未找到!\n");elseprintf("该元素在表中的位置为%d\n",locate); }。
