零基础学数据结构查找.pptx
《零基础学数据结构查找.pptx》由会员分享,可在线阅读,更多相关《零基础学数据结构查找.pptx(77页珍藏版)》请在淘文阁 - 分享文档赚钱的网站上搜索。
1、11.1 查找的基本概念 关键字(key)与主关键字(primary key):数据元素中某个数据项的值。如果该关键字可以将所有的数据元素区别开来,也就是说可以唯一标识一个数据元素,则该关键字被称为主关键字,否则被称为次关键字(secondary key)。特别地,如果数据元素只有一个数据项,则数据元素的值即是关键字。查找表(search table):是由同一种类型的数据元素构成的集合。查找表中的数据元素是完全松散的,数据元素之间没有直接的联系。第1页/共77页11.1 查找的基本概念 查找(searching):根据关键字在特定的查找表中找到一个与给定关键字相同的数据元素的操作。如果在表中
2、找到相应的数据元素,则称查找是成功的,否则,称查找是失败的。例如,表11.1中为教师基本情况,如果要查找职称为“教授”并且性别是“男”的教师,则可以先利用职称将记录定位,然后在性别中查找为“男”的记录。表11.1 教师基本情况信息表第2页/共77页11.1 查找的基本概念 对查找表经常进行的操作有(1)查询某个“特定的”的数据元素是否在查找表中;(2)检索某个“特定的”数据元素的各种属性;(3)在查找表中插入一个数据元素;(4)从查找表中删除某个数据元素。若对查找表只进行前两种查找操作,则称此类查找表为静态查找表(static search table),相应的查找方法称为静态查找(stati
3、c search)。若在查找过程中同时插入查找表中不存在的数据元素,或者从查找表中删除已存在的某个数据元素,则称此类查找为动态查找表(dynamic search table),相应的查找方法为动态查找(dynamic search)。第3页/共77页11.1 查找的基本概念 平均查找长度(average search length):是指在查找过程中,需要比较关键字的平均次数,它是衡量查找算法的效率标准。平均查找长度的数学定义为:ASL=。其中,Pi表示查找表中第i个数据元素的概率,Ci表示在找到第i个数据元素时,与关键字比较的次数。第4页/共77页11.2 静态查找 顺序表的查找 顺序表的
4、存储结构如下。#define MaxSize 100 typedef struct KeyType key;DataType;typedef struct DataType listMaxSize;int length;SSTable;第5页/共77页11.2 静态查找顺序表的查找算法描述如下:int SeqSearch(SSTable S,DataType x)/*在顺序表中查找关键字为x的元素,如果找到返回该元素在表中的位置,否则返回0*/int i=0;while(ix.key)/*从有序顺序表的最后一个元素开始向前比较*/i-;return i;第10页/共77页11.2 静态查找 设
5、表中的元素个数为n且要查找的数据元素在表中出现的概率相等即为,则有序顺序表在查找成功时的平均查找长度为:即查找成功时平均比较次数约为表长的一半。在查找失败时,即要查找的元素没有在表中,则有序顺序表在查找失败时的平均查找长度为:第11页/共77页11.2 静态查找 2折半查找 折半查找(binary search)又称为二分查找,这种查找算法要求待查找的元素序列必须是从小到大排列的有序序列。折半查找的算法描述如下:将待查找元素与表中间的元素进行比较,如果两者相等,则说明查找成功;否则利用中间位置将表分成两部分,如果待查找元素小于中间位置的元素值,则继续与前一个子表的中间位置元素进行比较;否则与后
6、一个子表的中间位置元素进行比较。不断重复以上操作,直到找到与待查找元素相等的元素,表明查找成功。如果子表变为空表,表明查找失败。第12页/共77页11.2 静态查找 一个有序顺序表为(7,15,22,29,41,55,67,78,81,99),如果要查找元素67。利用折半查找算法思想,折半查找的过程如图11.1所示。第13页/共77页11.2 静态查找折半查找的算法描述如下。int BinarySearch(SSTable S,DataType x)/*在有序顺序表中折半查找关键字为x的元素,如果找到返回该元素在表中的位置,否则返回0*/int low,high,mid;low=0,high=
7、S.length-1;/*设置待查找元素范围的下界和上界*/while(low=high)mid=(low+high)/2;if(S.listmid.key=x.key)/*如果找到元素,则返回该元素所在的位置*/return mid+1;else if(S.listmid.keyx.key)/*如果mid所指示的元素大于关键字,则修改high指针*/high=mid-1;return 0;第14页/共77页11.2 静态查找 折半查找过程可以用一个判定树来描述。例如,用折半查找算法查找值为56的元素时,需要比较4次。从图11.1中可以看出,查找元素41需要比较1次,查找元素78需要比较2次,
8、查找元素55需要比较3次,查找元素67需要比较4次。整个查找过程可以用二叉判定树来表示,如图11.2所示。第15页/共77页11.2 静态查找 对于具有n个结点的有序表(恰好构成一个深度为h的满二叉树)来说,有h=,二叉树中第i层的结点个数是2i-1。假设表中每个元素的查找概率相等,即Pi=,则有序表在折半查找成功时的平均查找长度为:查找失败时,有序表的折半查找失败时的平均查找长度为:第16页/共77页11.2 静态查找索引顺序表的查找 当顺序表中的数据量非常大时,无论使用前述哪种查找算法都需要很长的时间,此时提高查找效率的一个常用方法就是在顺序表中建立索引表。建立索引表的方法是将顺序表分为几
9、个单元,然后分别为这几个单元建立一个索引,我们把原来的顺序表称为主表,提供索引的表称为索引表。索引表中只存放主表中要查找的数据元素的主关键字和索引信息。图11.3是一个主表和一个按关键字建立的索引表结构图。第17页/共77页11.2 静态查找 我们把这样的表称为索引顺序表,要使查找效率高,索引表必须有序,但主表中的元素不一定要按关键字有序排列。索引顺序表的查找也称分块查找。因索引表中的元素的关键字是有序的,故在确定元素所在主表的单元时,既可采用顺序查找法也可采用折半查找法,但对于主表,只能采用顺序法查找。索引顺序表的平均查找长度可以表示为:ASL=Lindex+Lunit。其中,Lindex是
10、索引表的平均查找长度,Lunit是单元中元素的平均查找长度。假设主表中的元素个数为n,并将该主表平均分为b个单元,且每个单元有s个元素,即b=n/s。如果表中的元素查找概率相等,则每个单元中元素的查找概率就是1/s,主表中每个单元的查找概率是1/b。如果用顺序查找法查找索引表中的元素,则索引顺序表查找成功时的平均查找长度为:ASL成功=。第18页/共77页11.2 静态查找 当然,如果主表中每个单元中的元素个数是不相等的时候,就需要在索引表中增加一项,即用来存储主表中每个单元元素的个数。将这种利用索引表示的顺序表称为不等长索引顺序表。例如,一个不等长的索引表如图11.4所示。第19页/共77页
11、11.2 静态查找静态查找应用举例 【例11_1】给定一组元素序列,利用顺序表查找、有序顺序表查找和索引顺序表查找值x的元素。【分析】主要考察静态查找的3种算法思想。第20页/共77页11.3 动态查找 二叉排序树 二叉排序树也称为二叉查找树。二叉排序树的查找是一种常用的动态查找方法。下面介绍在二叉排序树中进行查找、二叉排序树的插入和删除结点。1什么是二叉排序树 所谓二叉排序树(binary sort tree),或者是一棵空二叉树,或者二叉树具有以下性质:(1)如果二叉树的左子树不为空,则左子树上的每一个结点的值均小于其对应根结点的值;(2)如果二叉树的右子树不为空,则右子树上的每一个结点的
12、值均大于其对应根结点的值;(3)该二叉树的左子树和右子树也满足性质(1)和(2),即左子树和右子树也是一棵二叉排序树。第21页/共77页11.3 动态查找 显然,这是一个递归的二叉排序树定义。例如,一棵二叉排序树如图11.6所示。从图11.6中不难看出,每个结点元素值都大于其所有左子树结点元素的值,且小于其所有右子树中结点元素值。例如,80大于左孩子的结点元素值70,小于右孩子结点元素值87。第22页/共77页11.3 动态查找 2查找算法 二叉排序树中每个结点的值都大于其所有左子树结点的值,而小于其所有右子树中结点的值。如果要查找与二叉树中某个关键字相等的结点,可以从根结点开始,与给定的关键
13、字比较,如果相等,则查找成功。如果关键字小于根结点的值,则在其左子树中查找。如果给定的关键字大于根结点的值,则在其右子树中查找。采用链式存储结构的二叉排序树的类型定义如下:typedef struct Node DataType data;struct Node*lchild,*rchild;BiTreeNode,*BiTree;第23页/共77页11.3 动态查找二叉排序树的查找算法描述如下。BiTree BSTSearch(BiTree T,DataType x)/*二叉排序树的查找,如果找到元素x,则返回指向结点的指针,否则返回NULL*/BiTreeNode*p;if(T!=NULL)
14、/*如果二叉排序树不为空*/p=T;while(p!=NULL)if(p-data.key=x.key)/*找到则返回指向该结点的指针*/return p;else if(x.keydata.key)/*如果关键字小于p指向的结点的值,则在左子树中查找*/p=p-lchild;else p=p-rchild;/*如果关键字大于p指向的结点的值,则在右子树中查找*/return NULL;第24页/共77页11.3 动态查找 假设存在一棵二叉排序树,在该二叉排序树中查找元素75的过程如图11.7所示。第25页/共77页11.3 动态查找 在二叉排序树的查找过程中,查找某个结点的过程正好是走了从根
15、结点到要查找结点的路径,其比较的次数正好是路径长度+1,这类似于折半查找,与折半查找不同的是由n个结点构成的判定树是唯一的,而由n个结点构成的二叉排序树则不唯一。例如,对于图11.8所示的两棵二叉排序树,其元素的关键字序列分别是66,35,81,23,47,69,92和23,35,47,66,69,81,92。第26页/共77页11.3 动态查找3 3二叉排序树的插入二叉排序树的插入二叉排序树的结构不是一次生成的,而是在查找的过程中,当树中不存在关键字等于给定值的结点时再进行插入。新插入的结点一定是一个新添加的叶子结点,并且是查找不成功时查找路径上访问的最后一个结点的左孩子或右孩子结点。因此,
16、可以说二叉排序树的插入操作过程其实就是二叉排序树的建立过程。在算法的实现过程中,需要设置一个指向下一个要访问结点的双亲结点指针parent,记下前驱结点的位置,以便在查找失败时进行插入操作。第27页/共77页11.3 动态查找二叉排序树的插入操作算法描述如下。int BSTInsert(BiTree*T,DataType x)/*二叉排序树的插入操作,如果树中不存在元素x,则将x插入到正确的位置并返回1,否则返回0*/BiTreeNode*p,*cur,*parent=NULL;cur=*T;while(cur!=NULL)if(cur-data.key=x.key)/*二叉树中存在元素为x的
17、结点,则返回0*/return 0;parent=cur;/*parent指向cur的前驱结点*/if(x.keydata.key)/*如果关键字小于p指向的结点的值,则在左子树中查找*/cur=cur-lchild;elsecur=cur-rchild;/*如果关键字大于p指向的结点的值,则在右子树中查找*/第28页/共77页11.3 动态查找 p=(BiTreeNode*)malloc(sizeof(BiTreeNode);/*生成结点*/if(!p)exit(-1);p-data=x;p-lchild=NULL;p-rchild=NULL;if(!parent)/*如果二叉树为空,则第一
18、结点成为根结点*/*T=p;else if(x.keydata.key)/*如果关键字小于parent指向的结点,则将x成为parent的左孩子*/parent-lchild=p;else/*如果关键字大于parent指向的结点,则将x成为parent的右孩子*/parent-rchild=p;return 1;第29页/共77页假设一个元素序列55,43,66,88,18,80,33,21,72,根据二叉排序树的插入算法思想,对应的二叉排序树插入过程如图11.9所示。11.3 动态查找第30页/共77页11.3 动态查找 4二叉排序树的删除 对于一般的二叉树来说,删去树中的一个结点是没有意义
19、的。因为它将使以被删结点为根的子树变成森林,破坏了整棵树的结构。然而对于二叉树来说,删除树中的一个结点其实是删除有序序列的一个记录,只要在删除某个结点之后依旧保持二叉树的特性即可。那么如何在二叉树排序树中删除一个结点呢?假设要删除的结点由指针s指示,指针p指向s的双亲结点,设s为f的左孩子结点。删除一个结点分为3种情况讨论。二叉排序树的各种删除情形如图11.10所示。第31页/共77页11.3 动态查找(1)如果s指向的结点为叶子结点,其左子树和右子树为空,删除叶子结点不会影响到树的结构特性,因此只需要修改p的指针即可。(2)如果s指向的结点只有左子树或只有右子树,在删除了结点*s后,只需要将
20、s的左子树sL或右子树sR作为f的左孩子即p-lchild=s-lchild或p-lchid=s-rchild。第32页/共77页(3)若s存在左子树和右子树,在删除结点T之前,二叉排序树的中序序列为QLQXLXYLYTTRP,因此,在删除了结点S之后,使该二叉树仍然保持原来的性质不变的调整方法有两种:(1)使结点T的左子树作为结点P的左子树,结点T的右子树作为结点Y的右子树。(2)使结点T的直接前驱取代结点T,并删除T的直接前驱结点Y,然后令结点Y原来的左子树作为结点X的右子树。如图11.10所示。11.3 动态查找第33页/共77页二叉排序树的删除操作算法描述如下。int BSTDelet
21、e(BiTree*T,DataType x)/*在二叉排序树T中存在值为x的数据元素时,删除该数据元素结点,并返回1,否则返回0*/if(!*T)/*如果不存在值为x的数据元素,则返回0*/return 0;elseif(x.key=(*T)-data.key)/*如果找到值为x的数据元素,则删除该结点*/DeleteNode(T);else if(*T)-data.keyx.key)/*如果当前元素值大于x的值,则在该结点的左子树中查找并删除之*/BSTDelete(&(*T)-lchild,x);else/*如果当前元素值小于x的值,则在该结点的右子树中查找并删除之*/BSTDelete(
22、&(*T)-rchild,x);return 1;11.3 动态查找第34页/共77页void DeleteNode(BiTree*s)/*从二叉排序树中删除结点s,并使该二叉排序树性质不变*/BiTree q,x,y;if(!(*s)-rchild)/*如果s的右子树为空,重接左子树*/q=*s;*s=(*s)-lchild;free(q);else if(!(*s)-lchild)/*如果s的左子树为空,重接右子树*/q=*s;*s=(*s)-rchild;free(q);11.3 动态查找第35页/共77页11.3 动态查找else/*如果s的左、右子树都存在,则使s的直接前驱结点代替s
23、,并使其直接前驱结点的左子树成为其双亲结点的右子树结点*/x=*s;y=(*s)-lchild;while(y-rchild)/*查找s的直接前驱结点,y为s的直接前驱结点,x为y的双亲结点*/x=y;y=y-rchild;(*s)-data=y-data;/*结点s被y取代*/if(x!=*s)/*如果结点s的左孩子结点存在右子树*/x-rchild=y-lchild;/*使y的左子树成为x的右子树*/else/*如果结点s的左孩子结点不存在右子树*/x-lchild=y-lchild;/*使y的左子树成为x的左子树*/free(y);第36页/共77页 5二叉排序树应用举例 【例11_2】
24、编写算法,利用二叉树的插入算法创建一棵二叉排序树树,然后输入一个元素,查找该元素是否存在,最后输出这棵树的中序序列。11.3 动态查找第37页/共77页平衡二叉树 若二叉排序树的深度为n,在最坏的情况下平均查找长度为n。因此,为了减小二叉排序树的查找次数,需要对二叉树排序树进行平衡化处理,平衡化处理得到的二叉树称为平衡二叉树。1什么是平衡二叉树 平衡二叉树(balanced binary tree)又称为AVL树,它或者是一棵空树,或者是具有以下性质的二叉树:它的左子树和右子树都是平衡二叉树,且左子树和右子树的深度之差的绝对值不超过1。11.3 动态查找第38页/共77页若将二叉树中结点的平衡
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 基础 数据结构 查找
限制150内