九章查找Search

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

i 1
A S L
Pi Ci
n
其中: n 为表长,Pi 为查找表中第i个记录的概率,假设
每次查找都是成功的,则有pi=1
Ci为找到该记录时,比较过的关键字的个数, Ci = n-i+1,ASL = nP1 +(n-1)P2 +…+2Pn-1+Pn,如果要
查找的元素在表中的任何位置的概率是相等的,p=1/n ,ASL=(n+1)/2
第九章 查找(Search)
9.1 基本概念 9.2 静态查找表 9.3 动态查找表 9.4 Hash表
9.1 基本概念
如何评估查找方法的优劣?
查找的过程就是将给定的值与文件中各记录的关
键字逐项进行比较的过程。所以用比较次数的平均值
来评估算法的优劣,称为平均查找长度(ASL:
average search length)。i1
三、索引顺序表的查找(分块查找)
分块查找的数据结构:
D={d1,d2,….,dn} 1. 将n个数据元素分为s个块 B1,B2, …, Bs ; 2. 块之间有序:Bi+1中的任一元素小于Bi中的任一元
return ERROR; T->data = R[i]; // 生成结点
if (i==low) T->lchild = NULL; // 左子树空 else SecondOptimal(T->lchild, R, sw, low, i-1);
// 构造左子树 if (i==high) T->rchild = NULL; // 右子树空 else SecondOptimal(T->rchild, R, sw, i+1, high);
// 构造右子树 return OK; } // SecondOptimal
次优查找树采用二叉链表的存储结构
Status CreateSOSTre(SOSTree &T, SSTable ST) { // 由有序表 ST 构造一棵次优查找树 T。 // ST 的数据元素含有权域 weight if (ST.length = 0) T = NULL; else { FindSW(sw, ST);
A S L
Pi Ci
其中:
n
n是文件记录个数;
Pi是查找第i个记录的查找概率; Ci是找到第i个记录时所经历的比较次数。
显然,ASL值越小,时间效率越高。
9.2 静态查找(搜索)表
静态查找表抽象数据类型 ADT StaticSearchTable {
Data: SET Operations:
Create(&ST, n): 创建具有n个元素的查找表。 Destroy( &ST): 销毁查找表。 Search(ST,key): 查找具有关键字key 的元素。 Traverse( ST,visit()): 遍历查找表。 }ADT StaticSearchTable
2).算法的实现:
int Search_Seq( SSTable ST , KeyType key ){
//在顺序表ST中,查找关键字与key相同的元素;若成 功,返回其位置信息,否则返回0。
ST.elem[0].key =key; for( i=ST.length; ST.elem[ i ].key!=key; - - i );
索引顺序表的特点是把若干个数据元素分成若干块,每一块 称为一个顺序表,要求块与块之间要有序,即第i+1块的所 有元素的关键字要大于第i块的所有元素的关键字。
为了查找方便,为每一块建立一个索引项: 索引项:(key,addr), key 域标记该块中最大记录的关键字,
addr域指向该块的起始地址。 索引表是由若干索引项组成的有序表。
再继续进行对分查找;
• L[mid].Key< x,把查找区间缩小到表的后半部分,
再继续进行对分查找。
每比较一次,查找区间缩小一半。如果查找区间已 缩小到一个记录,仍未找到想要查找的记录,则查 找失败。
查找成功的例子 比较序列:4[4],6[8],5[6]
查找失败的例子 4[4],6[8],5[6]
若查找概率事先无法测定,则为了提高查找效 率,可以在每个记录中附设一个访问频度域,使顺序 表中的记录保持按访问频度非递减有序排列,使得查 找频率大的记录在查找过程中不断往后移,以便在以 后的查找中减少比较次数,或者将刚刚查找到的记录 直接移至表尾的位置上。
4)优缺点
优点:算法简单且适应面广。 缺点:平均查找长度较大。
2)算法思想:
1 设n个记录存放在一个有序顺序表L中,并按其关键 码从小到大排好了序。查找范围为l=0, r=n-1;
2 求区间中间位置mid=(l+r)/2;
3 比较:
L[mid].Key = x,查找成功,返回mid,结束; L[mid].Key > x,r=mid-1; L[mid].Key < x,l=mid+1;
j1
达最小
i
为便于计算,引入累计权值和 swi wj j1
并设 wl-1 = 0 和 swl-1 = 0,
则推导可得 P i(sh w slw 1)siw siw 1
例如:
lh
h
lh
j 01234567
wj 0 2 1 5 3 4 3 5
s w j 0 2 3 8 11 15 18 23 Δ p j 21 18 12 4 3 10 18
}SSTable;
一、顺序查找
2).算法的实现: 编程技巧:把待查关键字key存入表头或表尾(俗 称“哨兵”),这样可以加快执行速度(避免每一 次查找都检测整个表是否查找完毕)。
例: 若将待查找的特定值key存入顺序表的首部 (如0号单元),则顺序查找的算法思想为: 从后向前逐个比较!
一、顺序查找
Status SecondOptimal(BiTree &T, ElemType R[], float sw[], int low, int high) {
// 由有序表R[low..high]及其累计权值表sw // 递归构造次优查找树T。
选择最小的ΔPi值 if (!(T = (BiTree)malloc(sizeof(BiTNode))))
4 若l<=r 转2,否则查找失败,返回 0;
考虑对单链表结构如何折半查找? ——无法实现!
2)算法实现:
int Search_Bin ( SSTable ST, KeyType key ) { // 在有序表ST中折半查找其关键字等于key的数据元素。 // 若找到,则函数值为该元素在表中的位置,否则为0。 low = 1; high = ST.length; // 置区间初值 while (low <= high) { mid = (low + high) / 2; if (key == ST.elem[mid].key) return mid; // 找到待查元素 else if ( key < ST.elem[mid].key) high = mid - 1; // 继续在前半区间进行查找 else low = mid + 1; // 继续在后半区间进行查找 } return 0; // 顺序表中不存在待查元素 } // Search_Bin
// 按照有序表 ST 中各数据元素 // 的 weight 值求累计权值表
SecondOpiamal(T, ST.elem, sw, 1, ST.length); } return OK; } // CreatSOSTree
三、索引顺序表的查找(分块查找)
索引顺序表的查找是鉴于顺序查找和折半查找的一种查找。 索引顺序表是由索引表和顺序表两部分组成。
3).顺序查找算法的平均查找长度(ASL)
如果有查找不成功的情况时,假设要查找的元素在表 中的概率是p,查找不成功的概率为q=1-p
查找成功的平均查找长度为ASL=p(n+1)/2
查找不成功的平均查找长度为q(n+1)
平均查找长度为
3).顺序查找算法的平均查找长度(ASL)
在不等概率查找的情况下, ASLss 在Pn≥Pn-1≥···≥P2≥P1时取极小值
所以:
•最坏情况下的查找长度是: T(n)lo2(g n)1
• 查找成功的平均查找长度: 设查找任一记录的概率都相等,即:pi=1/n 在第k层上最多有2k-1 个结点,在第k层上的结点需 比较k次。
所以:A S i n 1L p ic i 1 nk h 1k .2 k 1 n n 1 lo 2 (n g 1 ) 1
nn1lo2g(n1)1lo2g(n1)1
,且关键字有序
三、静态树表的查找(自学)
在概率不等的查找情况下,折半查找不是有序 表最好的查找方法。
例如: 关键字: A
B
C
D
E
Pi: 0.2 0.3 0.05 0.3 0.15
Ci: 2
31
2
3
此时 ASL=20.2+30.3+10.05+20.3+30.15=2.4
例:
索引表
最大关键字(key) 22 40 61 起始地址(addr) 1 7 13
22 15 13 8 17 20 35 24 33 40 36 29 50 48 60 49 54 61
第一块
第二块
第三块
三、索引顺序表的查找(分块查找)
有必要时可以在索引表上再建立索引表
稠密索引: 为每条记录设一个索引项。 稀疏索引:一组记录设一个索引项。
二、折半查找(二分或对分查找)
➢ 1)算法思想:
要求n个记录存放在一个顺序表L中,并按其关键码
从小到大排好了序,称此表为有序表。
先求位于查找区间正中的记录的下标mid,用其关键
码与给定值x比较:
• L[mid].Key == x,查找成功; • L[mid].Key> x,把查找区间缩小到表的前半部分,
若改变Ci的值 2 1
3
2
3
则 ASL=20.2+10.3+30.05+20.3+30.15=1.9
定义:
使
n
n1
ASLpiCi qiCi
i1
i1
达最小的判定树称为最优查找树,
n
n1
其中: pi qi 1
i1
i1
介绍一种次优二叉树的构造方法:
选择二叉树的根结点,
使
h
i1

Pi
wj wj
ji1
9.1 静态查找(搜索)表
静态查找表可用顺序表或单链表存储, 本章只讨论顺序表。
一、顺序查找(线性查找) 二、折半查找(二分或对分查找) 三、分块查找(索引顺序查找)
一、顺序查找(Linear search,又称线性查找)
所谓顺序查找,又称线性查找,主要用于在线性结构 中进行查找。
设若表中有 n 个记录,则顺序查找从表的先端开始,
//不要用for(i=n; i>0; - -i) 或 for(i=1; i<=n; i++) return i;
} // Search_Seq
同学们自己考虑对单链表如何线性查找?
一、顺序查找
3).顺序查找算法的平均查找长度(ASL)
为确定记录在查找表中的位置,需给定值进行比较的关
键字个数的期望值
96 08
53
12
k e y AA B CC D EE F GG
所得次优二叉树如下: E
C
A
D
F
B
查找比较“总次数” = 32+41+25+33 +14+33+25 = 52
和折半查找相比较
G
D
B
F
A
C
E
G
查找比较“总次数” = 32+21+35+13 +34+23+35 = 59
构造次优二叉树的算法
3)算法分析:
List[]: 1 2 3 4 5 6 7 8 9 10 11 12 13 14
2 4 6 8 10 13 15 18 20 22 24 25 27 30
15
6
24
2
10
20
27
48
13 18
22 25 30
折半查找的判定树:有2n+1个结点, 高度不超过完 全二叉树。
最多的比较次数不超过完全二叉树的高度:
顺序用各记录的关键码与给定值x进行比较,直到找到与
其值相等的记录,则称查找成功,给出该记录在表中的 位置。
若整个表都已检测完仍未找到关键码与x相等的记录,
则查找失败,给出失败信息。
一、顺序查找
1).顺序表的机内存储结构:
typedef struct { ElemType *elem; //表基址,0号单元留空。表容量为全部元素 int length; //表长,即表中数据元素个数
32 (h1)2 h2 )
2
h2
h1
i0
ni0
n
ASsuLc c PiCi 1 Ci 1(11221
n1
n1
可以用归纳法证明
1 12 2 1 3 2 2 (h 1 ) 2 h 2h 2 h 1 (h 1 ) 2 h 1
这样 ASsuLcc1 n(h (1)2h1)1 n(n (1)lo2g(n1)n)
相关文档
最新文档