一、基本概念
集合:数据元素同属一个集合,具有关键字值(键值)key[关键字是区分不同数据元素的关键信息,具有特异性],数据元素之间没有逻辑关系,集合两大核心操作是查找和排序
集合定义
template<class KEY,class OTHER> class Set{ KEY key;//关键字 Other other;//其他信息 }
查找表:用于查找的数据结构,分为静态查找表和动态查找表,静态查找表的数据元素个数和值都不变,动态查找表支持元素的插入、删除
查找:确定具有特定键值的数据元素在查找表中是否存在,可分为内部查找和外部查找,内部查找的性能通过平均查找长度(ASL,average search length)评估,外部查找性能通过访问外存速度评估{与外存访问相比,比较时间微不足道}
二、静态查找
静态查找表通常用数组来实现,第0个下标变量存放待查找的元素,查找成功返回下标,查找失败返回0
无序表的查找
无序表的查找方法:顺序查找,设置哨兵,从最后一个元素往前查找,时间复杂度O(n),ASL=(n+1)/2[成功查找],(n+2)/2[包含不成功查找]
有序表的查找
有序表的查找方法:①顺序查找(利用有序性),时间复杂度O(n);②二分查找,时间复杂度O(logn),ASL=[logN]-1(查找成功)[对于不成功的查找,查找次数是[logN]+1,对于成功的查找,最坏情况查找次数是[logN];
考点:分析二分查找的ASL成功/ASL失败
③插值查找(二分查找延伸,通过公式计算下一查找位置),要求数据分布比较均匀;
④分块查找(索引查找)。块之间必须是有序的,块内部可以无序。即i-1块的所有元素都大/小于i块的所有元素
对查找表分块建立索引表。索引表记录每个块的起始地址以及最大元素值,成为块的索引项。
查找分两步:查找索引和查找块
查找索引,根据每个块的最大元素值在索引表中进行有序查找
查找块,若块内无序,进行顺序查找,如果块内有序,可以采用顺序查找、二分查找。
假设表长为n,分为m块,则平均每块有n/m个元素,若索引查找和块内查找都采用顺序查找,则时间复杂度ASL=1/2(m+n/m)+1,当[最佳划分块数]时,查找效率最高,时间复杂度为O(根号n)。查找性能介于顺序查找和二分查找之间,并且不要求块内元素一定有序。
用查字典类比:
通过查找单词structure,首先通过A-Z索引,找到S块,接着进行块内查找,估计一下t应该在靠后的位置[二分查找/插值查找],往后翻字典,找到st后,使用顺序查找一个一个比较直到找到单词[顺序查找]。
STL中algorithm头文件包含两个查找元素,find,顺序查找,返回迭代器;binary_search,二分查找,返回布尔类型
iterator find(iterator it1,iterator it2,x)
bool binary_search(iterator it1,iterator it2,x)
三、动态查找
动态查找表的数据结构分为查找树和散列表。查找树可分为二叉查找树(BST)、平衡树、红黑树、伸展树和AA树。
1、平衡二叉树
BST特性:中序遍历递增
BST查找:
1、根节点不存在,查找失败
2、根结点的关键字值等于查找的关键字值,查找 成功;
3、根结点的关键字值小于查找的关键字值,递归查找左子树;否则递归查找右子树
BST插入(同BST查找)
BST删除
①叶子结点直接删除
②只有一个孩子结点
③有两个孩子结点[选大小相邻的替代]
BST性能:BST接近完全二叉树,时间复杂度O(logN);BST退化为单链表,时间复杂度O(N),n个结点的BST平均查找时间为1.38log2n
2、AVL树
AVL树:BST的升级版,具有有序性和平衡性
背景:插入和删除时,使二叉查找树尽可能平衡,以两位苏联科学家的名字命名
条件:每个结点平衡度绝对值小于等于1(平衡度:左子树的高度减去右子树的高度)
可以证明,一棵有N个结点的AVL树,高度最大为1.44log(N+1)-0.328,即最坏的情况下,AVL树操作时间复杂度都是对数级别的
四种失衡情况:
LL:原来A的左子树比右子树高,在左子树的左子树中插入新结点[右旋]
RR(LL镜像,左旋)
LR:原来A的左子树比右子树高,在左子树的右子树中插入新结点[小左旋,大右旋]
AVL树的插入:每插入一个结点,就要进行平衡检查,如果不平衡,则识别失衡状态,采取相应的解决方法,注意每次旋转后都要更新结点的高度。
AVL树的删除:
remove函数(参数一:查找值;参数二:根结点,返回值:布尔类型(判断删除后树的高度是否维持原状,如果返回true则不需要检查父结点平衡度,否则需要检查父结点是否失衡)):
1.key<root.key,在左子树中删除,若删除后左子树高度变矮,则调整根结点
2.key>root.key,在右子树中删除,若删除后右子树高度变矮 ,则调整根结点
3.key==root.key,删除根结点;
①如果根结点度为0,则直接删除根结点;若根结点度为1,则用该子树替代根结点
②若根结点度为2,找到右子树的最大结点,用其值替代根结点,然后在右子树中删除该结点,如果右子树变矮,调整该根结点
adjust函数(参数一:根结点,参数二:左子树(0)/ 右子树(1),返回值:布尔类型,判断调整后树是否维持原高度)
1.对于参数二为0,对应图1五种情况;
2.对于参数二为1,是上面的镜像情况(left->right,R->L,L->R)
3、红黑树
红黑树:
1、根结点是黑色的
2、结点是红色的,其子结点必须是黑色的,也就是说不能有连续的红结点
3、从结点沿任意路径到根结点,路径上的黑色结点数量相同
红黑树插入
红黑树插入四种情况
首先,插入结点为红色
1、父为黑,直接插入
2、父红叔红(爷与父/叔颜色交换)
3、父红叔黑,且爷父子共线,则爷父颜色交换,然后进行一次右旋或左旋
4、父红叔黑,但爷父子不共线,则先进行一次小旋转调整至共线,再按情况三处理
4、AA树
AA树是一种特殊的红黑树,限定了红结点不能作为左结点
平衡信息可用结点的层次表示,结点的层次指:结点到空路径上左链的数量,左儿子一定是黑结点,比父结点低一个层次,右儿子比父亲低0/1个层次,AA树可以用水平链表示
5、伸展树
6、散列表