数据结构第9章 查找

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

关键字
• 是数据元素的某个值,用于识别一个数据 元素 • 若此关键字可以识别唯一的记录称主关键 字 • 若此关键字可以识别多个记录则称次关键 字
• 若查找表中存在这样一个待查记录,则称 查找成功,给出结果,查找不成功,给出 空记录或空指针
• 查找方式,取决查找表的结构 • 如:查字典和查电话不同 • 为了提高查找效率需要在查找表加一些人 为的关系
i=1 i=1 n n+1 查找不成功项
其中 ∑pi +∑gi =1
i=1 i=1
n
n+1
次优查找树
• 不考虑查找不到的情况 • 次优查找树构造方法
– 令wi=α*pi(取整数) – 如何选择二叉树的根结点,使
h i-1
ΔPi=
j=i+1
∑wj -- ∑wj 最小
j=l
某结点左边概率之和和右边概率之和差值最小的,此结点作根结点
• 顺序表块预留空位,插入方便
9.2 动态查找表
• 表结构会发生改变
定义(同静态查找表)
• 数据对象D
– 具有相同特性的数据元素集合 – 每个元素含有类型相同的关键字,可唯一识别 数据元素
• 数据关系R
– 数据元素同属一个集合
基本操作
• initDSTable(&dt)
– 构造一个空表
• destroyDSTable(&dt) • searchDSTable(dt,key)
• 顺序查找
– ci=n-i+1:从后开始查,当i=n查1次,i=1查n次 – ASL=np1+(n-1)p2+…..+pn
• 等概率情况:p*(n+1)*n/2=(n+1)/2
• 在不等概率时,计算ASL,p取最小值 • 为了减少查找次数,可将查找概率大的靠 近表尾 • 如果查找的数不在查找表内,则每次要查n 次,此时的平均查找长度要大大增加
A Pi Ci 0.2 2 B C D E 0.15 3 0.3 B 0.3 A Pi 改变Ci 0.2 2 B C D E 0.15 3 0.2 0.05 A D 0.15 E 0.3 0.05 0.3 1 3 2 B 0.05 0.2 A D 0.15 E C 0.3 0.05 0.3 3 1 2 0.3
4).索引顺序表
• 无序表和有序表的查找性能之差别
无序表 (顺序表) 表的特性 存储结构 插入和删除 ASL 无序 顺序结构和链表结构 有序表 有序 顺序结构(链表结构因无法折半查找不用)
容易进行(添加或标记)需移动元素 大 小
两者都有优点,索引顺序表结合两者优点 索引顺序表=索引表+顺序表(无序表) 一般情况下索引是有序表
二叉排序树
50 30 80
20
40
90
10
25
35
85
23
88
中序遍历结果是有序序列,二叉排序树可以由无序序列构成
二叉排序树结构同二叉树
typedef int KeyType; /* 结点数据可以是含关键字的记录 typedef struct { KeyType key; ElemType data; } TElemType; */ typedef int TElemType; typedef struct BSTNode{ TElemType data; struct BSTNode *lchild,*rchild; }BSTNode,*BSTree;
折半查找:ASL=0.2*2+0.3*3+0.05*1+0.3*2+0.15*3=2.4
0.3
C
查找长度:ASL=0.2*2+0.3*1+0.05*3+0.3*2+0.15*3=1.9 结论:设计一个判定树,减少平均查找长度
最优静态查找树定义
• 使下式达最小的判定树称为最优静态查找 树
ASL=∑pici+∑gici’
折半查找的平均查找长度
• 折半查找判定树
– 折半查找过程可用二叉判定树描述
i Ci 1 3 2 4 3 2 4 3 5 4 6 1 7 3 8 4 6 9 2 10 11 3 4 二叉排序树 9 4 7 8 10
L=(1*1+2*2+3*4+4*4)/11=3
1
3
12个区域不成 功查找
2
5
11
静态查找表基本操作
• • • • create(&st,n) //构造含n个元素的查找表 destroy(&st) search(st,key)//返回等于关键字key的元素位置 Traverse(st,visit()) // 遍历查找表
静态查找表使用顺序结构的存储
typedef struct { ElemType *elem; //动态定义 int length; //元素个数 }SSTable; • 查找过程,数据不需移动
第九章查找表
查找表
• 同一类型的数据元素的集合
对查找表进行的操作
• • • • 查询某个特定的数据元素 检索特定的某个元素的属性 在查找表中插入一个数据元素 删除某个数据
• 静态查找表
– 仅查询和检索
• 动态查找表
– 查找到了要删除或者查找不到要插入
查找定义
• 根据给定的某个值,在查找表中查找
• 例:
I key 1 A 2 B 3 C 4 D 5 E 6 F 7 G 8 H 9 I 10 J 11 K
Wi
1
1
28 9 1
2
25 6 2
5
18 1
3
10 9
4
3
4
5 11
3
12 4
5
20 4 3
2
27 11 4
1
30 14 7
=31
Δpi 30 11 左:2 右:27 3
F D B A C K E H
st..length=10
st..length=10 待找的数据放在0位置就可以减少一种比较
按规则查找
int location(SqList l ElemType e,Status(*compare)(ElemType,ElemType)){ k=1; p=l.elem; while (k<=l.length && !(*compare)(*p++,e)); if (k<=l.length) return k;//返回位置>0 else return 0; } //从前往后找
– 字典按笔画建立索引,根据字的笔画到指定的 页面顺序查。 – 电话按用户性质、地区划分,要到所属区域查。
9.1 静态查找表
• 表数据在查找过程中不变
定义
• 数据对象D
– 具有相同特性的数据元素集合(无线性表特征) – 每个元素含有类型相同的关键字,可唯一识别 数据元素
• 数据关系R
– 数据元素同属一个集合
索引顺序表的组织和查找
• 查找方法:
– 由索引表确定记录所在的区间 – 在顺序表的某区间内顺序查找
• 类似班级和学生组织
块 顺序表key: 13 5 27 21 38 29 53 60 55 70 88 84
索引表key:
40 50
70 100 ……..
索引顺序表的平均查找长度
• 平均查找长度
– 在索引表中进行查找的平均查找长度+在顺序 表中进行查找的平均查找长度 – 索引表中可采用折半查找方法 – 设表长n,块长s(有n/s块),则 – ASL=log2(n/s+1)+s/2
2).有序查找表
• 查找表内的数据有序 • 折半查找
查75
初始 0 第1次后 5 5 1

low 13 19 2 3 21 4 37 5 56 6 m 13 19 21 37 56 64 7 75 8 low 64 75 80 88 80 9 88 10 high 92 11 high 92
0 第2次后
– 存在返回值或位置,否则为空
• insertDSTable(&dt,e);
– 若e不存在,则插入表
• deleteDSTable(&dt,key)
– 删除存在的数据元素
查找表的特性比较
查找 无序顺序表 无序线性链表 有序顺序表 有序线性链表
静态查找树表 比较结果: 1)插入,删除操作-----链表结构方便 2)查找长度--------------有序表短
1
2
3
4
5
6
7
8 low
9
m high 80
10
11
5
13 19
21
37
56
64
75
88
92
0
第3次后
1
2
3
4
5
6
7
m
8
9
low high
10
11
5 0 1
13 19 2 3
21 4
37 5
56 6
64 7
75 8
80 9 m
88 10
92 11
查76则low+1>high查找结束
int search_Bin(SSTable s,KeyType key){ low=1;high=st.length; while (low<=high){ mid=(low+high)/2; if (EQ(key,st.elem[mid].key)) return mid; else if (LT(key,st.elem[mid].key)) high=mid-1; else low=mid+1; } return 0; } • 例:search_BIN.c
分析顺序查找的时间性能
• 查找算法的平均查找长度 • 平均查找长度定义
– 为确定记录在查找表中的位置,需和给定值进 行比较的平均次数 – ASL=∑pici
• pi查找某数的概率 • ci查找某数的次数

• 10个数,每个数查1次,查10次
– 等概率pi=1/10 – 查第1个数1次,查第2个数2次,… – ASL=(1+2+3+…+10)*(1/10)=5.5 – 一般等概率情况:ASL=(n+1)/2
查找算法
• 二叉排序树为空,则:查找不成功 • 否则
– 若给定值等于根结点的关键字,则查找成功 – 若给定值小于根结点的关键字,则查找左子树 – 若给定值大于根结点的关键字,则查找右子树
• Status searchBST(BiTree t,KeyType key,BiTree f,BiTree &p){ • //引入参数f,f是p的前驱,p是找到结点 • if (!T){p=f;return FALSE; • else if (EQ(key,t->data.key)){ //找到 • p=t;return TRUE;} • else if (LT(key,t->data.key)) • searchBST(t->lchild,key,t,p);//左子树中找 • else searchBST(t->rchild,key,t,p);// 右子树中找 • }
静态查找表表示方法
• • • • 顺序查找表(无序) 有序查找表 静态查找树表 索引顺序表
1).顺序查找表
• 以顺序表或线性链表表示静态查找表
st.elem 21 0 1 0项不用 st.elem 60 0 21 37 1 2 88 3 19 4 92 5 5 6 64 7 56 8 80 9 75 10 37 2 88 3 19 4 92 5 5 6 64 7 56 8 80 9 75 10
• 一般情况下,表长为n的折半查找的判定树 和含有n个结点的完全二叉树的深度相同 • 假设n=2h-1,并且查找概率相同则 • ASL=(1/n) ∑i*2i-1=(n+1)/n*log2(n+1)-1在 n>50 • ASL=log2(n+1)-1=log2n
3).静态查找树表
• 不等概率查找情况下,折半查找不是最好 的查找方法,如:
按关键字查找
int search_Seq(SSTable st,keyType key){ st.elem[0].key=key;//设置哨兵
//从后往前找,终能找到,不用判断越界
for (i=st.length;st.elem[i].key!=key;--i); return i; //i==0 找不到,i>0找到 } //search_Seq 例:search_Seq.c
插入 O(1) O(1) O(n)
O(1) O(nlog2n)
删除 O(n) O(1) O(n)
O(1) O(nlog2n)
O(n) O(n) O(log2n)
O(n) O(log2n)
1.二叉排序树定义
• 或者是空树 • 或者具有如下特性
– 若左子树不空,则左子树所有结点的值均小于 根结点 – 若右子树不空,则右子树所有结点的值均大于 根结点 – 它的左、右子树分别是二叉排序树
G
I J
• Status secondOptimal(BiTree &t,ElemType r[],float sw[],int low,int high){ • //由有序表r[low,…,high]及累计权值表sw递归构造 次优查找树 • 选择最小的△pi 值 • t=(BiTree)malloc(sizeof(BiTNode)); • t->data=r[i]; • if (i==low) t->lchild=NULL; • else secondOptimaal(t->lchild,r,sw,low,i-1); • if(i==high)t->rchild=NULL; • else secondOptimal(t->rchild,sw,i+1,high); • }
相关文档
最新文档