典型查找算法PPT课件
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
if (K==ST.R[mid].key) return mid;
if (K<ST.R[mid].key) high=mid-1;
else low=mid+1;
}
return -1;
//查找失败
}
2020/6/7
20
算法分析
虽然折半查找的效率较高,但它要求被查找 序列事先按关键字排好序,而排序本身是一种很 费时的运算;另外,折半查找只适用于顺序存储 结构,因此,折半查找特别适用于那种一经建立 就很少改动、而又需要经常查找的线性表。
2020/6/7
8
9.1.4 基本概念
▪ 查找表:由同一类型的数据元素构成的集合。 ▪ 静态查找表:只做查找操作的查找表。 ▪ 动态查找表:在查找过程中做插入和删除操作的查
找表。 ▪ 关键字、主关键字、次关键字 ▪ 查找:根据给定的某个值,在查找表中确定一个其
关键字等于给定值的记录或数据元素。
2020/6/7
2020/6/7
4
9.1.2 问题的分析
用计算机来解决查找学生问题,通常需要做 以下工作:
第一,学生信息以什么形式表示和存储; 第二,查找的具体实现方法(算法)。
2020/6/7
5
学生信息的存储方式:
struct student
{
int
int
char ┆
num1; num2; name[12];
2020/6/7
2
9.1 实例:学生分配座位
• 9.1.1 问题描述 • 9.1.2 问题的分析 • 9.1.3 实现算法 • 9.1.4 基本概念
2020/6/7
3
9.1.1 问题描述
教室中的学生座位分配是一个最简单 的例子。假定某教室有35个座位,如果 不加限定任意就坐或按某种规律就座,则 要查找某学生时就要将待查找的学生与当 前座位上的学生进行比较。
▪ 顺序查找的特点:算法简单,但查找效率低。
2020/6/7
16
9.2.2 折半查找
▪ 折半查找又称为二分查找。
▪ 折半要求查找表是有序的。
▪ 折半查找的基本思想是:
▪首先将待查的K值与有序表R[0]到R[n-1]的中间
位置mid上的结点的关键字进行比较,若相等,
则查找完成;
▪否则,若R[mid].key>K,则说明待查找的结点
mid=(low+high)/2;
if(index[mid].key<k) low=mid+1
else high=mid-1;
} if(low<b) {
//在块中顺序查找
for(i=index[low].addr;i<=index[low].addr+s-1 && i<n;i++)
if(A[i].key==k) return i;
10
9.2 静态查找
• 9.2.1 顺序查找 • 9.2.2 折半查找 • 9.2.3 分块查找
2020/6/7
11
9.2 静态查找
查找过程中,进行如下操作:查询某个特定的数据元素是 否在查找表中或检索某个数据元素的各种属性。此查找表 称为静态查找表(Static Search Table)。
查找表定义为顺序存储的线性表,数据类型定义如下:
9m2id]
high
[05 13 19 21 37] 56 64 75 80 88
low
mid
high 92
05 13 19 [21 37] 56 64 75 80 88 low high 92
mid
查找K=21的过程(查找成功)
2020/6/7
18
[05 13 19 21 37 56 64 75 80 88
第9章 典型查找算法
• 顺序查找、折半查找和分块查找的方法 和算法,相应的平均查找长度
• 二叉排序树查找方法和算ห้องสมุดไป่ตู้,二叉平衡 树概念
• 散列表的概念,散列函数的构造方法, 处理冲突的方法及散列表各种运算的实 现算法
2020/6/7
1
第9章 典型查找算法
• 9.1 实例:学生分配座位 • 9.2 静态查找 • 9.3 动态查找 • 9.4 散列查找 • 本章总结
9
查找运算的主要操作是关键字的比较,所以, 通常把查找过程中对关键字需要执行的平均比 较次数(也称为平均查找长度)作为衡量一个 查找算法效率优劣的标准。
平均查找长度定义为:
n
ASL pici i 1
其中,n是结点的个数;pi 是查找第i个结 点的概率,ci 是找到第i个结点所需要的比
较次数
2020/6/7
2020/6/7
29
9.3.1 二叉排序树查找
二叉排序树(二叉搜索树、二叉查找树) : 或者是一棵空树,或是一棵有如下特性的非空二叉树: l 若它的左子树非空,则左子树上所有结点的关键字 均小于根结点的关键字。 l 若它的右子树非空,则右子树上所有结点的关键字 均大于等于根结点的关键字。 l 左、右子树本身又各是一棵二叉搜索树。
return -1;
}
return -1;
}
2020/6/7
27
算法分析
由于分块查找实际上是两次查找过程,所以分块查找的平均查找 长度是:查找索引表确定给定值所在块内的平均查找长度ASLb与 在块的查找关键值的平均查找长度ASLk之和。即ASL=ASLb+ASLk。
若用顺序查找确定所在块,则分块查找成功时的平均查找长 度为:
2020/6/7
21
9.2.3 分块查找
分块查找(索引顺序查找) 基本思想:
首先把一个线性表(即主表)按照一定的函数关系或条 件划分成若干个逻辑子表,为每个子表分别建立一个索引 项,由所有子表的索引项构成一个索引表。当进行分块查 找时,先根据所给的关键字查找索引表,从中查找出给定 值K刚好小于等于索引值的那个索引项,找到待查块,然 后再到主表中查找该块,从中查找待查的记录。
KeyType key;
int addr(link);
}IdxType;
在这种结构下,查找过程要分为两步:首先查找索 引表。因为索引表是有序表,所以可采用二分查找或顺 序查找,以确定给定值所在的块。因为块中的记录可以 是任意排列的,所以再在已确定的块中进行顺序查找。
2020/6/7
26
分块查找算法如下:
Typedef struct { DataNode R[maxsize]; int length; }SSTable;
2020/6/7
typedef struct
{ int number;
char name[10];
float score;
} DataNode; Typedef struct
{ DataNode R[maxsize]; int length; }SSTable;
A S L 1 L 2 b 1jb 1j 1 si s1i b 2 1 s2 1 1 2 (n s s) 1
2020/6/7
24
分块有序表的索引存储表示
2020/6/7
25
索引表结点的数据类型定义如下: #define MaxIndex <索引表的最大长度>
typedef struct{
2020/6/7
19
折半查找算法(low和high分别表示当前查找区
间的下界和上界)
int BINSEARCH(SSTable ST,keytype K)
{ int low,mid,high;
low=0; high=n-1;
while (low<=high)
{ mid=(low+high)/2; //整除
int IdxSerch(SeqList A[],IdxType index[],int b,KeyType k,int n) { //分块查找关键字为k的记录,索引表为index[0..b-1]
int low=0,high=b-1,mid,i;
int s=n/b;
//每块记录个数
while(low<=high) { //在索引表中进行二分查找,找到的位置放在low中
struct Elemtype //数据元素类型定义
{keytype key; //关键字项
┆
};
#define maxlen maxsize //分配的存储单元个数
struct ListSq
{ Elemtype e [maxsize];
int
len;
}; 2020/6/7
12
9.2.1 顺序查找
只可能在左表R[0]到R[mid-1]中,只需在左子表
中继续查找;否则在右子表中继续查找。这样,
经过一次键字的比较就缩小了一半的查找区间。
▪重复执行,直到找到关键字为K的元素或当前查
找区间为空(即表明查找失败)为止。
2020/6/7
17
[05 13 19 21 37 56 64 75 80 88
low
顺序查找(线性查找)基本思想:
从线性表的一端开始,依次将每个元素的关键字 同给定值K进行比较,若某元素关键字与K相等,则 查找成功;若所有元素都比较完毕,仍找不到关键字 为K的元素,则查找失败。
2020/6/7
13
9.2.1 顺序查找
typedef struct { keytype key;
datatype other; } DataNode;
// 表示座号 // 表示学号 // 表示姓名
};
struct list
{
Student stu[size]; //保存学生记录
Int
len;
//学生人数
};
2020/6/7
6
查找学生的方法:
从第一个学生开始,依次与查找的学生进 行比较。在查找过程中,若某个学生的记录与 所查找学生记录相等,则查找成功,返回该学 生在表中位置;若全部比较完毕,没有符合条 件的学生记录,则查找不成功,返回-1。
实现算法: (略)
索引表是有序的,所以在索引表上既可以采用顺序查 找,也可以采用折半查找,而每个块中的记录排列是任意 的,所以在块内只能采用顺序查找。
2020/6/7
23
平均查找长度为:
设将长度为n的表均匀分成b块,每块有s个记录, 则b=[n/s],查找表中每条记录的概率相等,则每块 查找的概率为1/b,块中每条记录的查找概率为1/s。 则顺序查找索引表时:
结论:二叉排序树中序遍历得到的必是一个有序序列。
2020/6/7
30
•
由图9.4可以看出,对二叉排序树进行中序遍历
,便可得到一个按关键码有序的序列,因此,一个无序
序列,可通过构一棵二叉排序树而成为有序序列。
2020/6/7
31
输入: 45,24,55,12,37,53,60,28,40,70
45
15
▪ 算法中监视哨R[0]的作用是为了在for 循环中省去判定防止下标越界的条件 i>0, 从而节省比较的时间。
▪ 顺序查找的平均查找长度为:
ASLsqi n1pici 1 ni n1i(n1)/2
▪ 有时,表中各结点的查找概率并不相等。因 此若事先知道表中各结点查找概率的分布情 况,则可将表中结点按查找概率从大到小排 列,以便提高顺序查找的效率。
low
9m2id]
high
05 13 19 21 37 56 [64 75 80 88
92] low
mid
high
05 13 19 21 37 56 64 75 80 [88
92]
mid high
low
05 13 19 21 37 56 64 75 80] [88
92
high low
查找K=85的过程(查找失败)
24
ib 1s b 1s 11n
A SLj i ( s) 1 bj 1 si 1 2 2 2s
若用二分查找确定所在块,则分块查找成功时的平均查找长度为 :
ASLlo2g(ns1)2s
2020/6/7
28
9.3 动态查找
• 9.3.1 二叉排序树查找 • 9.3.2 二叉平衡树
动态查找表特点:表结构本身是在查找过程中 动态生成的,即对于给定值key,若表中存 在关键字等于key的记录,则查找成功;否 则插入关键字为key的元素。
2020/6/7
7
9.1.3 实现算法
int search ( List &L , int s ) //从表L.stu[0],L.stu[1],……L.stu[n-1]的n个元 素中查找关键字为S的元素,若查找成功返回该生学号, 否则返回-1
{ int i; for (i=0; i<L.len; i++) if ( L.stu[i]==s) break; if (i<L.len) return L.stu[i].num2; else return -1; }
14
顺序查找算法:
int SEQSEARCH(SSTable ST,keytype K)
{ int i;
ST.R[0].key=K; //设置监视哨
for(i=ST.length ; ST.R[i].key!=K ; --i) ;
//从表尾开始向后扫描
return i;
//返回下标
}
2020/6/7