在这一章里,老师带着我们学习了数据处理中经常使用的一种操作-——查找。虽说之前在关于线性表与数组之间的对比研究中,我们仔细探讨了这两者的优缺点(详情可查看https://www.cnblogs.com/liuzhhhao/p/10545229.html),也曾谈到数组和线性表在查找操作中的优劣,只不过那时只是粗略讲了一下关于查找的知识,这一章我们将重点掌握顺序查找、折半查找、分块查找等查找方法,掌握二叉排序树的构造和查找方法,平衡二叉树,B-和B+树的特点和基本操作并熟练掌握散列表的构造方法,计算在各种查找方法在等概率情况下查找成功的平均查找长度。
一、线性表的查找
在学习查找方法之前,要先认识几个名词
查找表:由同一类型的数据元素或记录构成的集合
关键字:数据元素中某个数据项的值,可以唯一的标识一个记录或数据元素
平均查找长度(ASL):为了确定记录在查找表中的位置,需要对给定值进行比较的关键字个数的期望值
ASL=(p1*c1+p2*c2+...+pn*cn)/n 其中ci为查找表中第i个记录的概率
1、顺序查找:从表的一端开始,一次扫描记录的关键字
数据元素类型定义如下:
typedef struct { KeyType key;/*关键字域*/ InfoType otherinfo;/*其他域*/ }ElemType;
顺序表的定义如下:
typedef struct { ElemType *R;/*存储空间基地址*/ int length;/*当前长度*/ }SSTable;
顺序表的查找算法其一:
int Search_seq(SSTable ST,KeyInfo key) { for(i=0;i<ST.length;i++) if(ST.R[i]==key) return i+1; return 0; }
设置监视哨的顺序查找(其一的改进版!):个人感觉这个比较好用,理解起来也很容易
int Search_seq(SSTable ST,KeyType key) { ST.R[0].key=key;/*设置哨兵*/ for(i=ST.length;ST.R[i].key!=key;--i);/*从后往前找*/ rethrn i;/*情况最坏的是找不到关键字,此时i=0,也可以退出*/
查找成功:查找概率相同且进行顺序查找
在此前提下的ASL=(n+1)/2
时间复杂度:O(n)
优点:算法简单,适用于顺序结构与链式结构且无论关键字是否有序
缺点:平均查找长度较大且查找效率低
2、折半查找:要求采用顺序存储结构且表中按关键字有序排列(和顺序查找明显区分的地方)
从表的中间记录开始,如果给定值和中间记录的关键字相等,则查找成功;如果是大于的情况,则在表中大于中间记录的那一半中查找,重复操作直到查找成功,反之亦然。
int Search_Bin(SSTable ST,KeyType key) { low=1;high=ST.length; while(low<=high) { mid=(low+high)/2; if(key==ST.R[mid].key) return mid; else if (key<ST.R[mid].key) high=mid-1; else low=mid+1;} return 0 }
注意:循环执行的条件是iow<=high,not low<high!!!
查找成功时 ASL=log2 (n+1) -1 (当n比较大时)
时间复杂度:O(log2 n)
空间复杂度:O(1)---》与数据规模无关
3、分块查找
老师上课时没注意听,好像是被跳过去不讲了...
二、树表的查找
1、二叉排序树
定义:左子树所有结点的值均小于它的根结点的值 右子树所有结点的值均大于它的根结点的值
2、二叉排序树的递归查找
若二叉排序树为空,则查找失败
若非空,则将给定值key与根结点的关键字T->data.key进行比较
3、二叉排序树的插入、创建和删除
这一部分没有理解清楚QAQ...争取找时间来理解这一部分内容
4、平衡二叉树--AVL树
特点:左子树和右子树的深度之差的绝对值不超过1
左子树和右子树也是平衡树
平衡因子:该结点左子树和右子树的深度之差(-1、0、1)
时间复杂度:O(log2 n)
三、散列表的查找——通过对元素的关键字进行某种运算,直接求出元素的地址
1、常用术语:
散列函数和散列地址:在记录的存储位置p和其关键字key之间建立一个确定的对应关系H,使得p=H(key)
散列表:用以存储按散列函数计算得到的相应散列地址的数据记录的一个有限连续的地址空间
通常散列表的存储空间是一个一维数组,散列地址是数组的下标。
2、散列函数的构造方法
数字分析法
平方取中法
折叠法
除留余数法——H(key)=key%p(p为小于表长的最大质数)
在这一章中我掌握了顺序查找、折半查找,以及二叉排序树、平衡二叉树,散列表这些内容,在学习过程中还是有很多不理解的部分
例如B树和B+树,平衡二叉树的插入,创建等操作理解不能 (哭)果然是我的脑回路不太清晰的问题吗,想学好 心有余却力不足 欸...
下周目标:总结前几次小测丢分原因,复习前几周学习的内容,解决pta上的题目,过一个好的端午节(笑)