Ch.9 查找 §9.1 基本概念 查找和排序是两个重要的运算

Slides:



Advertisements
Similar presentations
王 子 坊 《洛陽伽藍記》 主講教師:張其昀.
Advertisements

第7章 樹與二元樹 (Trees and Binary Trees)
第 九 章 搜尋(Search) 課程名稱:資料結構 授課老師:_____________.
主讲:计算机工程学院 李兰 答疑地点:主教学楼B区213
第6章 二叉树和树 前面的章节主要讨论的是线性结构,二叉树和树属于非线性的结构。遍历非线性结构比线性结构要麻烦。
数据结构及应用算法教程(修订版) 配套课件.
数据结构概论 第2章 线性表 董黎刚 浙江工商大学信电学院
第十章 内部排序 知识点3:快速排序.
计算机软件技术基础 数据结构与算法(4).
数据结构——树和二叉树 1/96.
引入树 线性表、堆栈和队列都是线性结构,它们的共同特点:一对一; 计算机对弈中的一个格局可能有多个后继格局,用线性结构难以描述。
第六章 树和二叉树.
第5章 树( Tree )和二叉树 5.1 树的基本概念 5.2 二叉树 5.3 遍历二叉树和线索二叉树 5.4 树和森林
CH6 树和二叉树 6.1 树的定义和基本术语 6.2 二叉树 6.3 遍历二叉树和线索二叉树 6.4 树和森林
第8章 查找 在英汉字典中查找某个英文单词的中文解释;在新华字典中查找某个汉字的读音、含义;在对数表、平方根表中查找某个数的对数、平方根;邮递员送信件要按收件人的地址确定位置等等。可以说查找是为了得到某个信息而常常进行的工作。 计算机、计算机网络使信息查询更快捷、方便、准确。要从计算机、计算机网络中查找特定的信息,就需要在计算机中存储包含该特定信息的表。如要从计算机中查找英文单词的中文解释,就需要存储类似英汉字典这样的信息表,以及对该表进行的查找操作。本章将讨论的问题即是“信息的存储和查找”。
第八章 查找.
第十章 内部排序 10.1 概述 10.2 插入排序 直接插入排序 其他插入排序 希尔排序
数据结构 第6章 树和二叉树 什么是树和二叉树?? 二叉树的遍历 数据结构.
第8章 查找 数据结构(C++描述).
第六章 树和二叉树 6.1 树的定义和基本术语 6.2 二叉树 6.3 遍历二叉树和线索二叉树 6.4 树和森林 6.6 赫夫曼树及其应用.
Chapter 7 Search.
Tree(樹) 什麼是「樹」? 「樹」的範例 「樹」的定義 「樹」的表示法.
Linked List Operations
單向鏈結串列 Singly Linked Lists.
第6章 佇列(Queues) 6-1 佇列的基礎 6-2 佇列的表示法 6-3 環狀佇列 6-4 雙佇列.
第11章 查找 主要知识点 查找的基本概念 静态查找表 动态查找表 哈希表.
第8章 排序.
第十章 排序.
第10章 查找 10.1 查找的基本概念 10.2 顺序表查找 10.3 索引表查找 10.4 树表查找 10.5 哈希表查找.
第九章 排序 9.1排序的基本概念 9.2简单排序方法(复杂度 O(n2)) 9.3先进排序方法(复杂度 O(nLogn))
第9章 排序.
复习.
数 据 结 构 Ch.6 树 计 算 机 学 院 肖明军
搜尋資料結構 Search Structures.
第七章 搜索结构 静态搜索结构 二叉搜索树 AVL树.
第12章 樹狀搜尋結構 (Search Trees)
第六章 二叉树和树 6.1树的基本概念 6.2二叉树 6.3二叉树遍历 6.4线索二叉树 6.5树和森林 6.6树的应用(霍夫曼树及其编码)
程序设计期末复习 黎金宁
第2章 线性表 线性表抽象数据类型 顺序表 主要知识点 单链表 循环单链表 循环双向链表 静态链表 设计举例.
第5章 堆疊(Stacks) 5-1 堆疊的基礎 5-2 堆疊的表示法 5-3 堆疊的應用 - 運算式的計算與轉換
第5章 堆疊(Stacks) 5-1 堆疊的基礎 5-2 堆疊的表示法 5-3 堆疊的應用 - 運算式的計算與轉換
第九章 查找 2018/12/9.
进程操作.
第六章 树和二叉树.
第八章 查找表 8.1静态查找表 8.2动态查找表 8.3哈希表及其查找.
本章重点难点 重点:顺序查找、二分查找、二叉排序树查找以及散列表查找的基本思想和算法实现。
第3章 栈和队列(一).
数据结构与算法
数 据 结 构 Ch.4 串 计 算 机 学 院 肖明军
教 师:曾晓东 电 话: E_mail: 计算机软件技术基础 教 师:曾晓东 电 话: E_mail:
陈海明 副教授 信息学院 计算机系 电子信息类非计算机专业选修课 程序设计实践 陈海明 副教授 信息学院 计算机系
Ch.9 查找 §9.1 基本概念 查找和排序是两个重要的运算
第9章 内部排序 9.1 概述 9.2 插入排序 9.3 快速排序 9.4 选择排序 9.5 归并排序 9.6 基数排序
数据结构 第9章 查找 什么是查找?? 静态查找 动态查找 哈希表 数据结构.
第九章 查找表 9.1静态查找表 9.2动态查找表 9.3哈希表及其查找.
6.6 Huffman树及其应用 王 玲.
6.3 遍历二叉树和线索二叉树(知识点二) 遍历二叉树 一、问题的提出
第九章 查找 2019/2/16.
数据结构与数据库 习题课(2) 2016年11月25日.
数据结构 第八章 查找.
資料結構與C++程式設計進階 排序與搜尋 講師:林業峻 CSIE, NTU 6/ 14, 2010.
第六章 树和二叉树 学习要点 理解树的定义和基本术语,重点了解二叉树的定义、性质、存储结构; 掌握二叉树遍历的递归算法及它的典型运算;
9.1 基本概念 9.2 线性表的查找 9.3 树表的查找 9.4 哈希表的查找 9.5 各种查找方法的比较
第7章 樹與二元樹(Trees and Binary Trees)
資料結構使用Java 第9章 樹(Tree).
<编程达人入门课程> 本节内容 为什么要使用变量? 视频提供:昆山爱达人信息技术有限公司 官网地址: 联系QQ:
树和二叉树(一).
第1章 数据结构基础概论 本章主要介绍以下内容 数据结构研究的主要内容 数据结构中涉及的基本概念 算法的概念、描述方法以及评价标准.
void HeapSort(int *a, int n) //堆排序 { //建立堆 for(int i = n/2-1; i >= 0; i--) //非叶节点最大序号值为n/2 HeapAdjust(a, i, n); for(int j = n-1; j >
本节内容 1.二叉排序树的定义 2.二叉排序树的查找操作 3.二叉排序树的插入操作 4.二叉排序树的删除操作 5.二叉排序树的总结
Presentation transcript:

Ch.9 查找 §9.1 基本概念 查找和排序是两个重要的运算 对象:表、文件等。其中每个结点(记录)由多个数据项构成,假设每个结点有1个能唯一标识该结点的key。 定义:给定1个值K,在含有n个结点的表中找出关键字等于K的结点,若找到(查找成功),则返回该结点信息或它在表中的位置;否则(查找失败),返回相关指示信息。 分类: 查找过程中是否修改表?动态查找、静态查找 查找过程是否均在内存中进行?内部查找、外部查找

§9.1 基本概念 效率:与存储结构、文件状态(有序、无序)有关 平均查找长度(ASL),即平均的比较次数,作为衡量查找效率的标准: Pi:查找第i个结点的概率 Ci:查找第i个结点的比较次数 设Pi=1/n, 1≤i≤n 约定:typedef int KeyType;

§ 9.2 线性表的查找 §9.2.1 顺序查找 对象:用线性表作为表的组织形式。 分类:静态查找、内部查找 方式:顺序查找、二分查找、分块查找 #define n 100// §9.2.1 顺序查找 基本思想 从表的一端开始,顺序扫描线性表,依次将扫描到的结点的Key与给定值K进行比较,若当前扫描到结点Key=K,则查找成功返回;若扫描完整个表后,仍未找到,则查找失败。 适用范围:顺序表、链表 算法:

§9.2.1 顺序查找 typedef struct{ KeyType key; InfoType otherinfo; //应用相关 }NodeType, SeqList[n+1]; //0号单元作为哨兵 int SeqSearch( SeqList R, KeyType K) { //在R[1..n]中查找,成功时返回结点位置,失败时返回0 int n; R[0].key=K; //设置哨兵 for ( i=n; R[i].key != K; i-- ); //从后往前找 return i; //若i为0,则失败 }

§9.2.1 顺序查找 哨兵的作用 for中省略了下标越界i>=1判定,节约了约一半时间 时间分析 优缺点 成功:ASLss=(n+1)/2,key的平均比较次数约为表长的一半 失败:n+1次比较 优缺点 优点:简单,对存储结构、Key之间的关系均无特殊要求 缺点:效率低,当n较大时不宜用

§ 9.2.2 二分(折半)查找 适用范围:顺序表、有序 基本思想(分治法) (1)设R[low..high] 是当前查找区间,首先确定该区间的中点 位置:mid= (low+high)/2 //整除 (2)将待查的K值与R[mid]比较, ① K=R[mid].key:查找成功,返回位置mid ② K<R[mid].key:则左子表R[low..mid-1]是新的查找区间 ③ K>R[mid],key:则右子表R[mid+1..high]是新的查找区间 初始的查找区间是R[1..n],每次查找比较K和中间点元素,若查找成功则返回;否则当前查找区间缩小一半,直至当前查找区间为空时查找失败。

§ 9.2.2 二分(折半)查找 算法: int BinSearch( SeqList R, KeyType K ) { int mid, low=1, high=n; while ( low < high ) { //当前查找区间R[low..high]非空 mid= (low+high)/2; //整除 if ( R[mid].key==K )return mid; //成功返回位置mid if ( K<R[mid].key ) //两个子问题求解其中的一个 high=mid-1; //在左区间中查找 else low=mid+1;//在右区间中查找 } // endwhile return 0; //当前查找区间为空时失败 }

查找过程 判定(比较)树:分析查找过程的二叉树,形态只与结点数相关,与输入实例的取值无关(为什么?)。例如n=11的形态如下图所示。 1 2 3 4 5 6 7 8 9 10 11 (05,13,19,21,37,56,64,75,80, 88, 92),找21成功,找85失败。 内部结点 R[1..11] 6 外部结点 R[1..5] R[7..11] = < > 9 3 R[10..11] R[1..2] R[4..5] R[7..8] 1 7 10 4 R[11..11] Φ R[2..2] R[8..8] Φ R[5..5] Φ Φ 11 2 8 5 9-10 3-4 6-7 -1 Φ Φ Φ Φ Φ Φ Φ Φ 11- 1-2 2-3 4-5 5-6 7-8 8-9 10-11

§ 9.2.2 二分(折半)查找 时间分析 查找R[6]:比较1次; 查找R[3]、R{9]:比较2次; 查找R[1]、R[4]、R[7]、R[10]:比较3次; 查找R[2]、R[5]、R[8]、R[11]:比较4次 6 R[1..11] 1 9 4 3 7 10 2 R[1..5] R[7..11] R[10..11] R[5..5] Φ R[11..11] -1 4-5 1-2 2-3 3-4 R[1..2] R[2..2] 5 8 R[4..5] 5-6 6-7 7-8 11 R[7..8] R[8..8] 8-9 9-10 11- 10-11 = > <

§ 9.2.2 二分(折半)查找 时间分析 总结:查找过程走了一条从判定树的根到被查结点的路径。 成功:终止于一个内部结点,所需的Key比较次数恰为该结点在树中的层数; 失败:终止于一个外部结点,所需的Key比较次数为该路径上内部结点总数。(层数-1) 平均查找长度(ASL): 设n=2h-1, 则树高h=lg(n+1) //不计外部结点的满二叉树 第k层上结点数为2k-1,找该层上每个结点的比较次数为k,在等概率假设下: 最坏时间:查找失败,不超过树高 ⌈lg(n+1)⌉ 在链表上可做折半查找吗?

§ 9.2.3 分块查找(索引顺序查找) 22 48 86 1 7 13 最大关键字 起始地址 存储结构 关键字状态 将R[1..n]均分成b块,前b-1块中结点数为s=⌈n/b⌉ ,最后一块中的结 点数可能小于s,引入索引表标记块。 关键字状态 分块有序:块间有序,块内不一定有序; 例子:n=18,b=3,s=6 22 48 86 1 7 13 最大关键字 起始地址 22 12 13 8 9 20 33 42 44 38 24 48 60 58 74 49 86 53

§ 9.2.3 分块查找(索引顺序查找) 查找过程(两步查找) 性能分析 EX.9.3 索引表查找:确定块。n较大时用折半查找,n较小时用顺序查找。 块内查找:只能顺序查找。 性能分析 以折半查找确定块: ASL= ASLbs+ASLss=lg(b+1) -1+(s+1)/2≈lg(n/s+1)+s/2 以顺序查找确定块: ASL= ASLss+ASLss=(b+1)/2+(s+1)/2=(s2+2s+n)/(2s) 当s= 时,ASL取极小值 +1 块不一定等分 EX.9.3

§ 9.3 树上的查找(动态查找) 折半查找效率最高,但它不适应插删操作。本节讨论适用于动态查找,即查找过程中动态维护表结构。 § 9.3.1 二叉查找树(BST) 定义:二叉查找树或是空树,或满足下述BST性质的二叉树: ①若它的左子树非空,则左子树上所有结点的keys均小于根的key ②若它的右子树非空,则右子树上所有结点的keys均大于根的key ③左右子树又都是二叉查找树 Note:性质1或2中,可以将“﹤” 改为“≤”;或“﹥”改为“≥” BST性质 二叉查找树的中序序列是一个递增有序序列

§ 9.3.1 二叉查找树(BST) 5 3 7 2 9 4 举例 存储结构: typedef struct node { KeyType key; InfoType otherinfo; struct node *lchild, *rchild; } BSTNode, *BSTree; 5 3 7 2 9 4

BSTNode *SearchBST( BSTree T, KeyType key ){ 5 3 7 2 9 4 1.查找 基本思想 从根结点开始比较,若当前结点的key与待查的key相等,则查找成功,返回该结点的指针;否则在左子树或右子树中继续查找。若树中没有待查结点,则失败于某个空指针上。 算法 BSTNode *SearchBST( BSTree T, KeyType key ){ //在T上查找key=K的节点,成功时返回该节点,否则返回NULL if ( T==NULL || key==T->key ) return T; //若T为空,查找失败;否则成功 if ( key < T->key ) return SearchBST ( T->lchild, key ); //查找左子树 else return SearchBST ( T->rchild, key ); //查找右子树 }

§ 9.3.1 二叉查找树(BST) 5 3 7 2 9 4 1.查找 时间 若成功,则走了一条从根到待查节点的路径 若失败,则走了一条从根到叶子的路径?(不一定) 上界:O(h) 分析:与树高相关 ①最坏情况:单支树,ASL=(n+1)/2,与顺序查找相同 ②最好情况:ASL≈lgn,形态与折半查找的判定树相似 ③平均情况:假定n个keys所形成的n!种排列是等概率的,则可证明由这n!个序列产生的n!棵BST(其中有的形态相同)的平均高度为O(lgn),故查找时间仍为O(lgn)

2、BST的插入和生成 插入 算法思想 保证新结点插入后满足BST性质,基本思想如下: 若T为空,则为待插入的Key申请一个新结点,并令其为根; 否则,从根开始向下查找插入位置,直到发现树中已有Key,或找到一个空指针为止; 将新结点作为叶子插入空指针的位置。 查找过程是一个关键字的比较过程,易于写出递归或非递归算法,也可以调用查找操作。 算法实现

2、BST的插入和生成 } //注意:树为空时,无须查找 void InsertBST( BSTree *T, KeyType key ) { //*T是根 BSTNode *f, *p=*T; //p指向根结点 while( p ) { //当树非空时,查找插入位置 if ( p->key==key ) return; //树中已有key,不允许重复插入 f=p;// f和p为父子关系 p=( key < p->key ) ? p->lchild; p->rchild; } //注意:树为空时,无须查找 p = (BSTNode *) malloc(sizeof(BSTNode)); p->key=key; p->lchild=p->rchild=NULL; //生成新结点 if ( *T ==NULL ) * T=p; //原树为空,新结点为根 else //原树非空, 新结点作为*f的左或右孩子插入 if ( key < f->key ) f->lchild=p; else f->rchild=p; } //时间为O(h)

2、BST的插入和生成 生成 } 算法: 从空树开始,每输入一个数据就调用一次插入算法。 算法: 从空树开始,每输入一个数据就调用一次插入算法。 BSTree CreateBST( void ) { BSTree T=NULL; //初始时T为空 KeyType key; scanf( “%d”, &key ); while( key ) { //假设key=0表示输入结束 InsertBST ( &T, key ) ; //将key插入树T中 scanf( “%d”, &key );// 读入下一个关键字 } return T;// 返回根指针

2、BST的插入和生成 举例 输入实例 {10, 18, 3, 8, 12, 2, 7, 3} 10 18 3 8 12 2 7

不同的输入实例(数据集不同、或排列不同),生成的树的形态一般不同。对n个结点的同一数据集,可生成n!棵BST。 一般情况 不同的输入实例(数据集不同、或排列不同),生成的树的形态一般不同。对n个结点的同一数据集,可生成n!棵BST。 例外情况 但有时不同的实例可能生成相同的BST,例如:(2,3,7,8,5,4)和(2,3,7,5,8,4)可构造同一棵BST。 排序树名称的由来 因为BST的中序序列有序,所以对任意关键字序列,构造BST的过程,实际上是对其排序。 生成n个结点的BST的平均时间是O(nlgn), 但它约为堆排序的2-3倍,因此它并不适合排序。

3、BST的删除 保证删一结点不能将以该结点为根的子树删去,且仍须满足BST性质。即:删一结点相当于删有序序列中的一个结点。 基本思想 查找待删结点*p,令parent指向其双亲(初值NULL);若找不到则返回,否则进入下一步。 在删除*p时处理其子树的连接问题,同时保持BST性质不变。 case1:*p是叶子,无须连接子树,只需将*parent中指向*p的指针置空 case2:*p只有1个孩子,只须连接唯一的1棵子树,故可令此孩子取代*p与 其双亲连接(4种状态) parent p child parent p child child parent p parent p child *p只有左孩子 *p只有右孩子

3、BST的删除 基本思想 case3: *p有2个孩子,有2种处理方式: ①找到*p 的中序后继(或前驱)*s,用*p的右(或左)子树取代*p与其双亲*parent连接;而*p的左(或右)子树PL则作为*s的左(或右)子树与*s连接。缺点:树高可能增大。 PL sR p parent s pr PL sR s pr parent

3、BST的删除 基本思想 ②令q=p,找*q的中序后继*p,并令parent指向*p的双亲,将*p的右子树取代*p与其双亲*parent连接。将*p的内容copy到*q中,相当于删去了*q,将删*q的操作转换为删*p的操作。对称地,也可找*q的中序前驱 因为*p最多只有1棵非空的子树,属于case2。实际上case1也是case2的特例。因此,case3采用该方式时,3种情况可以统一处理为case2。 q=p parent p child q=p p child *q的中序后继就是其右孩子

3、BST的删除 算法 void DelBSTNode( BSTree *T, KeyType key) { //*T是根 BSTree *q, *child, *parent=NULL, *p=*T; while ( p ) { //找待删结点 if ( p->key ==key ) break; //已找到 parent=p; //循环不变式是*parent为*p的双亲 p=( key < p->key ) ? p->lchild; p->rchild; } if ( !p ) return; //找不到被删结点,返回 q=p; //q记住被删结点*p if (q->lchild && q->rchild ) //case3,找*q的中序后继 for(parent=q,p=q->rchild; p->lchild; parent=p, p=p->lchild);

3、BST的删除 //现在3种情况已统一到情况2,被删结点*p最多只有1个非空的孩子 child=(p->lchild)?p->lchild; p->rchild; //case1时child空,否则非空 If ( !parent ) //*p的双亲为空,说明 *p是根,即删根结点 *T=child; //若是情况1,则树为空;否则*child取代*p成为根 else { //*p非根,它的孩子取代它与*p的双亲连接,即删 *p if ( p==parent->lchild ) parent->lchild=child; else parent->rchild=child; if ( p != q ) //情况3,将*p的数据copy到*q中 q->key=p->key; //若有其他数据亦需copy } free( p ); //删除*p } //时间O(h)

3、平衡二叉树和平衡的二叉查找树 平衡机制 AVL树:4种旋转 平衡二叉树 任一结点的左右子树高度大致相同,即只要二叉树高度为O(lgn),则可认为它是平衡的。 完全平衡二叉树 任一结点的左右子树高度完全相同(满二叉树) 平衡的二叉查找树 满足BST性质的平衡二叉树 AVL树:任一结点的左右子树的高度之差的绝对值不超过1,h≈1.44lgn 红黑树:h≈2lgn 平衡机制 AVL树:4种旋转 红黑树:2种旋转