第八章查找方案
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
}
26
二叉排序树的建立
其基本思想为:由一棵空二叉 树开始,经过一系列的查找插 入操作生成一棵二叉排序树。
例:{45,24,53,45,12, 24,90}
27
举例:若从空树出发,经过一系列的查 找插入操作之后,可生成一棵二叉树。 设查找的关键字序列为{45,24,53, 45,12,24,90},则生成的二叉排序 树如图所示。二叉排序树生成:从空树 出发,经过一系列的查找、插入操作之 后,可生成一棵二叉排序树。
1
log
2
(n
+
1)
-
1
对于任意的n,当n较大(n>50时),可有下列近似结果:
ASLbs = log 2 (n + 1) - 1
可见,折半查找的效率比顺序查找高,但折半查找只适用于
有序表,且限于顺序存储结构。
14
三、索引顺序表的查找(分块查找)
若以索引顺序表表示静态查找表,则search函数可用分块查找来实现。分块查找又称索引顺序查找, 这是顺序查找的一种改进方法。在此查找法中,除表本身以外,尚需要建立一个“索引表”。
二叉排序树的根结点;否则,若给 定结点的关键字值小于根结点关键 字值,则插入在左子树上;若给定 结点的关键字值大于根结点的值, 则插入在右子树上。
25
二叉排序树的插入算法
void bt_insert(BitTree bt , BitNode *pn) {if ( bt ==NULL) bt = pn ;
P
Q
S
PL
Q
PL
中序遍历:PL P S Q 中序遍历:PL S Q
(1)
S
S
QP
Q PL
PL 中序遍历:Q S PL P
21
一、二叉树排序树及其查找过程
1、什么是二叉排序树?
45
12
3
37
24
53 100
61 90
78
22
2、查找过程
45 12
3
37
24
53 100
61 90
78
23
查找算法
BiTNode *bt_search(BiTTree bt , KeyType key){
if ( bt ==NULL) return NULL ; if ( bt -> key== key ) return bt;
从判定树上可见,查21的过程恰好是走了一条从根到结点21 的路径,和给定值进行比较的关键字个数为该路径上的结点 数或结点4在判定树上的层次数。
12
2、折半查找的性能分析
查找成功时和给定值进行比较的关键
字个数至多为log2n+1
则:ASL
=
n
pici
i=1
=
1 n
n
ci
i=1
=
1 n
else low=mid+1; }
17
if(low >high) i=low; j=B[i].start; while ( j< B[i].start+ B[i].length)
主表*/ if (k ==A[j].key) break; else j++; if ( j< B[i].start+ B[i].length) return j; else return -1;
int low=1,high=B.length,i,j; while(low<=high) /*折半查找索引表*/ { int mid=(low+high)/2;
if (k == B[mid].index) {i=mid;break;} else if (k<B[mid].index) high=mid-1;
int low,high,mid; low = 1; high = A.length; /* 初始查找区间为整个表 */ while (low <= high) {
10
mid=(low+high)/2; /* 计算中间结点位置 */ if (key == A[mid].key) return mid;/* 找到key值,返回对应结点的
h
j
2
j-1
j=1
=
n+ n
1
log
2
(n
+ 1)
-1
对于任意的n,当n较大(n>50时), 可有下列近似结果:
ASL bs = log 2 (n + 1) - 1
13
二分法查找在查找成功时进行比较的关键字个数最多不超过
树的深度,而具有n个结点的判定树的深度为log2n+1。所 以折半查找法在查找成功时和给定值进行比较的关键字个数
28
容易看出,中序遍历二叉树可得
到一个关键字的有序序列。这就
45
是说,一个无序序列可以通过构
造一棵二叉排序树而变成一个有
24
序序列,构造树的过程即为对无
序序列进行排序的过程。
12
53 90
从上面的插入过程还可以看到,每次插入的新的结点都是二叉 排序树上新的叶子结点,则在进行插入操作时,不必移动其它 记录,仅需要改动某个结点的指针,由空变为非空即可。这就 相当于在一个有序序列上插入一个记录而不需要移动其它记 录。它表明,二叉排序树既拥有类似折半查找的特性,又采用 了链表作存储结构,因此是动态查找表的一种适宜表示。
找70
low
mid
123456 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
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
下,ASLss 在 Pn≥Pn1≥···≥P2≥P1时取极小值。
6
二、有序表的查找(折半查找)
1、折半查找
1)、初始状态 2)、让key与mid指向的记录比较
若key==r[mid].key,查找成功,算法结束 若key<r[mid].key,则high=mid-1 若key>r[mid].key,则low=mid+1 重复上述操作,直至low>high时,查找
1 2 3 4 5 6 7 8 9 10 11 5 13 19 21 37 56 64 75 80 88 92
这个查找过程可用图所示的二叉树 来描述。树中每个结点表示表中一
56
19
80
个记录,结点中的值为该记录在表 5 21 64 88
中的位置,通常称这个描述查找过 13 37 75
92
程的二叉树为判定树。
15
三、索引顺序表的查找(分块查找)
最大关键字 起始地址
索引表
27 47 82 0 7 11
查38
27 13 8 9 12 5 6 35 43 38 47 59 58 79 82 52
1、分块查找方法
16
int Blocksearch(indextable B, sstable A , keytype k) /* 在主表A中查找值为K的元素位置 */ {
123456
low high
mid 7 8 9 10 11
5 13 19 21 37 56 64 75 80 88 92
9
high low
int BinarySearch(SStable A, keytype key) /* 用折半查找算法在表A中查找key值,若找到, 返回其下标值,否则返回-1 */ {
3
#define MAX_NUM 100 //用于定 义表的长度 typedef struct datatype{
KeyType key; …… int length; }SStable[MAX_NUM],Se_Item;
4
比较次数=5
例 0 1 2 3 4 5 6 7 8 9 10 11 64 5 13 19 21 37 56 64 75 80 88 92
失败。 7
例如:已知如下11个数据元素的有序表(05,13,19,
21,37,56,64,75,80,88,92),现要查找关键
字为21和70 的数据元素。
找21
例 1 2 3 4 5 6 7 8 9 10 11 5 13 19 21 37 56 64 75 80 88 92
low
mid
1234来自百度文库6 7 5 13 19 21 37 56 64
下标 */ else if (key>A[mid].key) /* 继续查找后半部
分 */ low = mid+1;
else /* 继续查找前半部分 */ high = mid-1; }
return -1; /* 未找到,返回-1 */ } }
11
2、折半查找的性能分析
先看上述11个元素的表的具体例子。每一个的比较次数。
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
low mid high
8
例 1 2 3 4 5 6 7 8 9 10 11 5 13 19 21 37 56 64 75 80 88 92
else if ( bt -> key== key ) return NULL; else if ( bt -> key > pn->key ) bt_insert( bt -> lchild , pn ) ; else if ( bt -> key < pn -> key ) bt_insert( bt -> rchild , pn) ;
else if ( bt -> key > key ) bt_search ( bt -> lchild , key ) ;
else if ( bt -> key < key ) bt_search ( bt -> rchild , key) ; }24
二、二叉排序树的插入与删除
1、二叉排序树的插入 若二叉排序树为空,则新结点作为
第8章 查找
8.1 静态查找表 8.2 动态查找表 8.3 哈希表(散列表和查
找)
5/25/2019
1
第8章 查找
8.1 静态查找表
一、顺序查找 二、有序表的查找(折半查找) 三、索引顺序表的查找(分块查
找)
5/25/2019
2
一、顺序查找
1、顺序查找的基本思想 (1)顺序表的顺序查找
例 0 1 2 3 4 5 6 7 8 9 10 5 13 19 21 37 56 64 75 80 88 92 找64
例如:下图所示为一个表及其索引表,表中含有18个记
录,可分成三个子表(R1,R2,…,R6)、(R7, R8,…,R12)、(R13,R14,…,R18)。
索引表 22 48 86 1 7 13
查38
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 22 12 13 8 9 20 33 42 44 38 24 48 60 58 74 57 86 53
}
/*顺序查找
18
2、分块查找的平均查找长度
分块查找的平均长度为:ASLbS=Lb+Lw
其中Lb为查找索引表确定所在块的平均
查找长度,Lw为在块中查找元素的平均
查找长度。
ASLbs
=
Lb
+ Lw
=
1 b
b
j+
j=1
1
s
i
s i=1
=
b +1 + 2
s +1 2
= 1 (n + s) +1
29
2、二叉排序树的删除
假设在二叉排序树上被删结点为*P, 其双亲结点为*S,且不失一般性,可 设*P是*S的左孩子。要删除二叉排序 树中的P结点,分三种情况:
(1) *P为叶子结点
(2) *P只有左子树PL或右子树PR
(3) *P左、右子树均非空
30
(2) *P只有左子树PL或右子树PR
S
至多为log2n+1
树中层数为1的结点有1个,层数为2的结点有2个,层数为h
的结点有2h-1个。假设表中每个记录的查找概率
Pi
=
1 ,则查
n
找成功时折半查找的平均查找长度为:
则:ASL =
n i =1
pi ci
=1 n
n
ci
i =1
=1 n
h j =1
j 2 j-1 =
n
+ n
2s 19
静态表查找方法比较
顺序查找 二分查找 分块查找
ASL 最大
最小 两者之间
表结构 有序表 无序表
有序表 分块有序 表
存储结 顺序存储 顺序存储结 顺序存储
构 结构
构
结构
线性链表
线性链表 20
8.2 动态查找表
一、二叉树排序树及其查找过程 二、二叉排序树的插入与删除 三、二叉排序树的查找分析 四、平衡二叉树
iiii i
监视哨
找64
(2). 链表的顺序查找
5
2、查找操作的性能分析
查找成功:ASL = nP1 +(n-1)P2 + …+2Pn-1+Pn
设表中每个元素的查找概率相等pi
=
1 n
则ASL
=
n
pici
i=1
=
1 n
n
(n
i=1
-
i
+1)
=
1 n
×n(n +1) 2
=
n
+1 2
从上式可知,在不等概率查找的情况
26
二叉排序树的建立
其基本思想为:由一棵空二叉 树开始,经过一系列的查找插 入操作生成一棵二叉排序树。
例:{45,24,53,45,12, 24,90}
27
举例:若从空树出发,经过一系列的查 找插入操作之后,可生成一棵二叉树。 设查找的关键字序列为{45,24,53, 45,12,24,90},则生成的二叉排序 树如图所示。二叉排序树生成:从空树 出发,经过一系列的查找、插入操作之 后,可生成一棵二叉排序树。
1
log
2
(n
+
1)
-
1
对于任意的n,当n较大(n>50时),可有下列近似结果:
ASLbs = log 2 (n + 1) - 1
可见,折半查找的效率比顺序查找高,但折半查找只适用于
有序表,且限于顺序存储结构。
14
三、索引顺序表的查找(分块查找)
若以索引顺序表表示静态查找表,则search函数可用分块查找来实现。分块查找又称索引顺序查找, 这是顺序查找的一种改进方法。在此查找法中,除表本身以外,尚需要建立一个“索引表”。
二叉排序树的根结点;否则,若给 定结点的关键字值小于根结点关键 字值,则插入在左子树上;若给定 结点的关键字值大于根结点的值, 则插入在右子树上。
25
二叉排序树的插入算法
void bt_insert(BitTree bt , BitNode *pn) {if ( bt ==NULL) bt = pn ;
P
Q
S
PL
Q
PL
中序遍历:PL P S Q 中序遍历:PL S Q
(1)
S
S
QP
Q PL
PL 中序遍历:Q S PL P
21
一、二叉树排序树及其查找过程
1、什么是二叉排序树?
45
12
3
37
24
53 100
61 90
78
22
2、查找过程
45 12
3
37
24
53 100
61 90
78
23
查找算法
BiTNode *bt_search(BiTTree bt , KeyType key){
if ( bt ==NULL) return NULL ; if ( bt -> key== key ) return bt;
从判定树上可见,查21的过程恰好是走了一条从根到结点21 的路径,和给定值进行比较的关键字个数为该路径上的结点 数或结点4在判定树上的层次数。
12
2、折半查找的性能分析
查找成功时和给定值进行比较的关键
字个数至多为log2n+1
则:ASL
=
n
pici
i=1
=
1 n
n
ci
i=1
=
1 n
else low=mid+1; }
17
if(low >high) i=low; j=B[i].start; while ( j< B[i].start+ B[i].length)
主表*/ if (k ==A[j].key) break; else j++; if ( j< B[i].start+ B[i].length) return j; else return -1;
int low=1,high=B.length,i,j; while(low<=high) /*折半查找索引表*/ { int mid=(low+high)/2;
if (k == B[mid].index) {i=mid;break;} else if (k<B[mid].index) high=mid-1;
int low,high,mid; low = 1; high = A.length; /* 初始查找区间为整个表 */ while (low <= high) {
10
mid=(low+high)/2; /* 计算中间结点位置 */ if (key == A[mid].key) return mid;/* 找到key值,返回对应结点的
h
j
2
j-1
j=1
=
n+ n
1
log
2
(n
+ 1)
-1
对于任意的n,当n较大(n>50时), 可有下列近似结果:
ASL bs = log 2 (n + 1) - 1
13
二分法查找在查找成功时进行比较的关键字个数最多不超过
树的深度,而具有n个结点的判定树的深度为log2n+1。所 以折半查找法在查找成功时和给定值进行比较的关键字个数
28
容易看出,中序遍历二叉树可得
到一个关键字的有序序列。这就
45
是说,一个无序序列可以通过构
造一棵二叉排序树而变成一个有
24
序序列,构造树的过程即为对无
序序列进行排序的过程。
12
53 90
从上面的插入过程还可以看到,每次插入的新的结点都是二叉 排序树上新的叶子结点,则在进行插入操作时,不必移动其它 记录,仅需要改动某个结点的指针,由空变为非空即可。这就 相当于在一个有序序列上插入一个记录而不需要移动其它记 录。它表明,二叉排序树既拥有类似折半查找的特性,又采用 了链表作存储结构,因此是动态查找表的一种适宜表示。
找70
low
mid
123456 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
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
下,ASLss 在 Pn≥Pn1≥···≥P2≥P1时取极小值。
6
二、有序表的查找(折半查找)
1、折半查找
1)、初始状态 2)、让key与mid指向的记录比较
若key==r[mid].key,查找成功,算法结束 若key<r[mid].key,则high=mid-1 若key>r[mid].key,则low=mid+1 重复上述操作,直至low>high时,查找
1 2 3 4 5 6 7 8 9 10 11 5 13 19 21 37 56 64 75 80 88 92
这个查找过程可用图所示的二叉树 来描述。树中每个结点表示表中一
56
19
80
个记录,结点中的值为该记录在表 5 21 64 88
中的位置,通常称这个描述查找过 13 37 75
92
程的二叉树为判定树。
15
三、索引顺序表的查找(分块查找)
最大关键字 起始地址
索引表
27 47 82 0 7 11
查38
27 13 8 9 12 5 6 35 43 38 47 59 58 79 82 52
1、分块查找方法
16
int Blocksearch(indextable B, sstable A , keytype k) /* 在主表A中查找值为K的元素位置 */ {
123456
low high
mid 7 8 9 10 11
5 13 19 21 37 56 64 75 80 88 92
9
high low
int BinarySearch(SStable A, keytype key) /* 用折半查找算法在表A中查找key值,若找到, 返回其下标值,否则返回-1 */ {
3
#define MAX_NUM 100 //用于定 义表的长度 typedef struct datatype{
KeyType key; …… int length; }SStable[MAX_NUM],Se_Item;
4
比较次数=5
例 0 1 2 3 4 5 6 7 8 9 10 11 64 5 13 19 21 37 56 64 75 80 88 92
失败。 7
例如:已知如下11个数据元素的有序表(05,13,19,
21,37,56,64,75,80,88,92),现要查找关键
字为21和70 的数据元素。
找21
例 1 2 3 4 5 6 7 8 9 10 11 5 13 19 21 37 56 64 75 80 88 92
low
mid
1234来自百度文库6 7 5 13 19 21 37 56 64
下标 */ else if (key>A[mid].key) /* 继续查找后半部
分 */ low = mid+1;
else /* 继续查找前半部分 */ high = mid-1; }
return -1; /* 未找到,返回-1 */ } }
11
2、折半查找的性能分析
先看上述11个元素的表的具体例子。每一个的比较次数。
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
low mid high
8
例 1 2 3 4 5 6 7 8 9 10 11 5 13 19 21 37 56 64 75 80 88 92
else if ( bt -> key== key ) return NULL; else if ( bt -> key > pn->key ) bt_insert( bt -> lchild , pn ) ; else if ( bt -> key < pn -> key ) bt_insert( bt -> rchild , pn) ;
else if ( bt -> key > key ) bt_search ( bt -> lchild , key ) ;
else if ( bt -> key < key ) bt_search ( bt -> rchild , key) ; }24
二、二叉排序树的插入与删除
1、二叉排序树的插入 若二叉排序树为空,则新结点作为
第8章 查找
8.1 静态查找表 8.2 动态查找表 8.3 哈希表(散列表和查
找)
5/25/2019
1
第8章 查找
8.1 静态查找表
一、顺序查找 二、有序表的查找(折半查找) 三、索引顺序表的查找(分块查
找)
5/25/2019
2
一、顺序查找
1、顺序查找的基本思想 (1)顺序表的顺序查找
例 0 1 2 3 4 5 6 7 8 9 10 5 13 19 21 37 56 64 75 80 88 92 找64
例如:下图所示为一个表及其索引表,表中含有18个记
录,可分成三个子表(R1,R2,…,R6)、(R7, R8,…,R12)、(R13,R14,…,R18)。
索引表 22 48 86 1 7 13
查38
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 22 12 13 8 9 20 33 42 44 38 24 48 60 58 74 57 86 53
}
/*顺序查找
18
2、分块查找的平均查找长度
分块查找的平均长度为:ASLbS=Lb+Lw
其中Lb为查找索引表确定所在块的平均
查找长度,Lw为在块中查找元素的平均
查找长度。
ASLbs
=
Lb
+ Lw
=
1 b
b
j+
j=1
1
s
i
s i=1
=
b +1 + 2
s +1 2
= 1 (n + s) +1
29
2、二叉排序树的删除
假设在二叉排序树上被删结点为*P, 其双亲结点为*S,且不失一般性,可 设*P是*S的左孩子。要删除二叉排序 树中的P结点,分三种情况:
(1) *P为叶子结点
(2) *P只有左子树PL或右子树PR
(3) *P左、右子树均非空
30
(2) *P只有左子树PL或右子树PR
S
至多为log2n+1
树中层数为1的结点有1个,层数为2的结点有2个,层数为h
的结点有2h-1个。假设表中每个记录的查找概率
Pi
=
1 ,则查
n
找成功时折半查找的平均查找长度为:
则:ASL =
n i =1
pi ci
=1 n
n
ci
i =1
=1 n
h j =1
j 2 j-1 =
n
+ n
2s 19
静态表查找方法比较
顺序查找 二分查找 分块查找
ASL 最大
最小 两者之间
表结构 有序表 无序表
有序表 分块有序 表
存储结 顺序存储 顺序存储结 顺序存储
构 结构
构
结构
线性链表
线性链表 20
8.2 动态查找表
一、二叉树排序树及其查找过程 二、二叉排序树的插入与删除 三、二叉排序树的查找分析 四、平衡二叉树
iiii i
监视哨
找64
(2). 链表的顺序查找
5
2、查找操作的性能分析
查找成功:ASL = nP1 +(n-1)P2 + …+2Pn-1+Pn
设表中每个元素的查找概率相等pi
=
1 n
则ASL
=
n
pici
i=1
=
1 n
n
(n
i=1
-
i
+1)
=
1 n
×n(n +1) 2
=
n
+1 2
从上式可知,在不等概率查找的情况