幸运52猜数游戏
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
int IdxSearch(IDX I,int m,SeqList R,int n,KeyType k)
{ int low=0,high=m-1,mid,i;
int b=n/m;
/*b为每块的记录个数*/
while (low<=high) /*在索引中二分查找*/
{ mid=(low+high)/2;
typedef struct node { KeyType key;
索引表的数据类型定义如下:
#define MAXI <索引表的最大长度>
typedef struct
{ KeyType key; /*KeyType为关键字的类型*/
int link;
/*指向对应块的起始下标*/
} IdxType;
typedef IdxType IDX[MAXI]; /*索引表类型*/
<
5
=
2 < =>
> 8
<= >
0 < =>
-∞~-1
1
< =>
3 <= >
2~3
4
<=>
6 <=>
5~6
7
<=>
9 <=>
8~9
10
< =>
0~1 1~2
3~4 4~5
6~7
7~8
9~10 10~∞
R[0..10]的二分查线的判定树(n=11)
例 8.1 对 于 给 定 11 个 数 据 元 素 的 有 序 表 {2,3,10,15,20,25,28,29,30,35,40}, 采 用 二 分 查 找 , 试 问:
返回
采用何种查找方法?
(1) 使用哪种数据结构来表示“表”,即表中记录是按 何种方式组织的。
(2) 表中关键字的次序。是对无序集合查找还是对有序 集合查找?
若在查找的同时对表做修改运算(如插入和删除),则
相应的表称之为动态查找表,否则称之为静态查找表。
由于查找运算的主要运算是关键字的比较,所以通 常把查找过程中对关键字需要执行的平均比较次数(也 称为平均查找长度)作为衡量一个查找算法效率优劣的 标准。平均查找长度ASL(Average Search Length)定义 为:
n
ASL pici i1
其中,n是查找表中记录的个数。pi是查找第i个记 录的概率,一般地,均认为每个记录的查找概率相等,即 pi=1/n(1≤i≤n),ci是找到第i个记录所需进行的比较次数。
8.2 线性表的查找
在表的组织方式中,线性表是最简单的一种。三种 在线性表上进行查找的方法:
(1) 顺序查找 (2) 二分查找 (3) 分块查找。 因为不考虑在查找的同时对表做修改,故上述三种 查找操作都是在静态查找表上实现的。
时返回记录的位置,失败时返回-1):
int BinSearch(SeqList R,int n,KeyType k) { int low=0,high=n-1,mid;
while (low<=high) { mid=(low+high)/2;
if (R[mid].key==k) /*查找成功返回*/ return mid;
查找与数据的存储结构有关,线性表有顺序和链式 两种存储结构。本节只介绍以顺序表作为存储结构时 实现的顺序查找算法。定义被查找的顺序表类型定义 如下:
#define MAXL <表中最多记录个数>
typedef struct
{ KeyType key;
/*KeyType为关键字的数据类型*/
InfoType data;
return i; else
return -1; } return -1; }
若以二分查找来确定块,则分块查找成功时的 平均查找长度为:
s1
s
ASLblk ASLbn ASLsq log2 (h 1) 1 2 log2 (n / s 1) 2
若以顺序查找确定块,则分块查找成功时的平 均查找长度为:
int SeqSearch(SeqList R,int n,KeyType k) { int i=0;
while (i<n && R[i].key!=k) i++; /*从表头往后找*/ if (i>=n)
return -1; else
return i; }
从顺序查找过程可以看到(不考虑越界比较
i<n),ci取决于所查记录在表中的位置。如查找表中 第1个记录R[0]时,仅需比较一次;而查找表中最后
例如,设有一个线性表,其中包含25个记录,其关键字序列 为{8,14,6,9,10,22,34,18,19,31,40,38,54,66, 46,71,78,68,80,85, 100, 94,88,96,87}。假设将25个记录分为5块,每块中有5个记 录,该线性表的索引存储结构如下图所示。
14 34 66 85 100 key 0 5 10 15 20 link
例如,在关键字有序序列{2,4,7,9,10,14,18,26,32,40} 中采用二分查找法查找关键字为7的元素。
二分查找过程如下:
开始: 2 4 7 9 10 14 18 26 32 40
low=0
high=9 mid=(0+9)/2=4
第1次比较: 2 4 7 9 10 14 18 26 32 40
if (R[mid].key>k) /*继续在R[low..mid-1]中查找*/ high=mid-1;
else low=mid+1; /*继续在R[mid+1..high]中查找*/
} return -1; }
二分查找过程可用二叉树来描述,我们把当前 查找区间的中间位置上的记录作为根,左子表和右 子表中的记录分别作为根的左子树和右子树,由此 得到的二叉树,称为描述二分查找的判定树或比较 树。
8 14 6 9 10 22 34 18 19 31 40 38 54 66 46 71 78 68 80 85 100 94 88 96 87 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
采用二分查找索引表的分块查找算法如下(索 引表I的长度为m):
/*其他数据*/
} NodeType;
typedef NodeType SeqList[MAXL]; /*顺序表类型*/
8.2.1 顺序查找 顺序查找是一种最简单的查找方法。
它的基本思路是:从表的一端开始,顺序扫描线性表, 依次将扫描到的关键字和给定值k相比较,若当前扫描 到的关键字与k相等,则查找成功;若扫描结束后,仍未 找到关键字等于k的记录,则查找失败。
二叉排序树(简称BST)又称二叉查找(搜索)树,其定 义为:二叉排序树或者是空树,或者是满足如下性 质的二叉树:
(1) 若它的左子树非空,则左子树上所有记录的 值均小于根记录的值;
(2) 若它的右子树非空,则右子树上所有记录的 值均大于根记录的值;
(3) 左、右子树本身又各是一棵二叉排序树。
在讨论二叉排序树上的运算之前,定义其结点的类 型如下:
if (I[mid].key>=k) high=mid-1;
else low=mid+1;
}
if (low<m) /*在块中顺序查找*/ { i=I[low].link;
while (i<=I[low].link+b-1 && R[i].key!=k) i++; if (i<=I[low].link+b-1)
第19讲 第八章 查找
幸运52猜数游戏
由用户选择一个商品,让计算机猜该商品的价格(1-100 元),猜完后用户确定“对”或“错”,如果“对”,则游 戏结束;如果“错”,则计算机提问:“价格比实际价格要 高吗?”用户确定: “对”或“错”。计算机继续猜下一个 价格直到猜中为止。
8.1 查找的基本概念
ASLblk
ASL bn
ASL sq
b1 s1 22
s2
2s n 2s
8.3 树表的查找
当表的插入或删除操作频繁时,为维护表的有 序性,需要移动表中很多记录。这种由移动记录引 起的额外时间开销,就会抵消二分查找的优点。也 就是说,二分查找只适用于静态查找表。若要wenku.baidu.com动 态查找表进行高效率的查找,可采用下面介绍的几 种特殊的二叉树或树作为表的组织形式,在这里将 它们统称为树表。下面将讨论在二叉排序树上进 行查找和修改操作的方法。
i=2 第4次比较: 3 9 1 5 8 10 6 7 2 4
i=3 第5次比较: 3 9 1 5 8 10 6 7 2 4
i=4 第6次比较: 3 9 1 5 8 10 6 7 2 4
i=5 第7次比较: 3 9 1 5 8 10 6 7 2 4
i=6 查找成功,返回序号6
顺序查找的算法如下(在顺序表R[0..n-1]中查找关 键字为k的记录,成功时返回找到的记录位置,失败时返 回-1):
例如,在关键字序列为{3,9,1,5,8,10,6,7,2,4}的线性 表查找关键字为6的元素。
顺序查找过程如下:
开始: 3 9 1 5 8 10 6 7 2 4
第1次比较: 3 9 1 5 8 10 6 7 2 4
i=0 第2次比较: 3 9 1 5 8 10 6 7 2 4
i=1 第3次比较: 3 9 1 5 8 10 6 7 2 4
一个记录R[n-1]时,需比较n次,即ci=i。因此,成功时 的顺序查找的平均查找长度为:
n
1 n 1 n(n 1) n 1
ASLsq
p
i1
i
ci
i n i1
n
2
2
查找成功时的平均比较次数约为表长的一半 。
8.2.2 二分查找
二分查找也称为折半查找要求线性表中的结点必 须己按关键字值的递增或递减顺序排列。它首先用要 查找的关键字k与中间位置的结点的关键字相比较,这 个中间结点把线性表分成了两个子表,若比较结果相 等则查找完成;若不相等,再根据k与该中间结点关键 字的比较大小确定下一步查找哪个子表,这样递归进 行下去,直到找到满足条件的结点或者该线性表中没 有这样的结点。
(1)若查找给定值为20的元素,将依次与表中哪 些元素比较?
(2)若查找给定值为26的元素,将依次与哪些元 素比较?
(3)假设查找表中每个元素的概率相同,求查找 成功时的平均查找长度和查找不成功时的平均查 找长度。
二分查 找判定 树
25
10
30
2
15
28
35
3
20
29
40
(1) 若 查 找 给 定 值为20的元素,依次 与 表 中 25,10,15,20 元素比较,共比较4 次。
对于幸运52猜数游戏,我们采用二分查找 来实现比较好,请同学们自行完成C语言程序 来实现该游戏。
8.2.3 分块查找
分块查找又称索引顺序查找,它是一种性能介于 顺序查找和二分查找之间的查找方法。
它要求按如下的索引方式来存储线性表:将表 R[0..n-1]均分为b块,前b-1块中记录个数为s=n/b,最 后一块即第b块的记录数小于等于s;每一块中的关键 字不一定有序,但前一块中的最大关键字必须小于后 一块中的最小关键字,即要求表是“分块有序”的; 抽取各块中的最大关键字及其起始位置构成一个索 引 表 IDX[0..b-1], 即 IDX[i](0≤i≤b-1) 中 存 放 着 第 i 块 的 最大关键字及该块在表R中的起始位置。由于表R是 分块有序的,所以索引表是一个递增有序表。
(2)若查找给定值为26的元素,依次与25,30,28元素比较,共比 较3次。
(3)在查找成功时,会找到图中某个圆形结点,则成功时的平
均查找长度:
ASLsucc=1 1 2 2 4 3 4 4=3 11
在查找不成功时,会找到图中某个方形结点,则不成功
时的平均查找长度:
ASLunsucc=4 3 8 4=3.67 12
被查找的对象是由一组记录组成的表或文件,而每个记录 则由若干个数据项组成,并假设每个记录都有一个能惟一标 识该记录的关键字。
在这种条件下,查找的定义是:给定一个值k,在含有n个记 录的表中找出关键字等于k的记录。若找到,则查找成功,返 回该记录的信息或该记录在表中的位置;否则查找失败,返 回相关的指示信息。
low=0 high=3
mid=(0+3)/2=1
第2次比较: 2 4 7 9 10 14 18 26 32 40
low=2 high=3
mid=(2+3)/2=2
第3次比较: 2 4 7 9 10 14 18 26 32 40
R[2].key=7 查找成功,返回序号2
其算法如下(在有序表R[0..n-1]中进行二分查找,成功