目录
1、顺序查找、折半查找、分块查找
1、平均查找长度是衡量查找算法优劣的标准。
2、动态查找:分块查找、二叉排序树、散列查找
3、静态查找:顺序查找、折半查找、散列查找
1、顺序查找:
- 哨兵作用:从尾部开始查找,减少不必要的语句,从而提高效率。
- 平均查找长度:(成功:(n+1)/2)(失败:n)
- 成功查找:只与其位置有关,与其是否有序无关
2、折半查找:二分
- 要求有序且顺序存储、不可链式存储
- 树高为【lg(n+1)上取整】,且比较次数不会超过树的高度。
- 能不能构成比较序列:写出二叉排序树,看是否符合要求
- 折半查找判定树:①不可能绝对对称。②所有子数必须保持同一种规则(要么只能左多,要么只能右多)
3、分块查找:
- 块内无序、每个分块的块间有序
4、三者总结:
- 存储结构:顺序查找和分块查找适合顺序表和链表,折半查找只适合顺序表。
- 平均查找长度:分块(最小)、折半(中间)、顺序(最大)
2、二叉排序树
1、二叉排序树目的:
- 不是为了排序,是为了提高查找、插入、删除关键字的效率(与树的高度有关)
- 平均查找长度:与树的高度有关、时间复杂度O(lgn)~O(n)
- 左小右大
2、二叉排序树的插入、删除:
- 插入:
- 删除:若有左右孩子,则找该结点左子树的最大值或右子树的最小值。(无需移动指针,只用修改指针即可)
5、平衡二叉树
1、平衡二叉树:
- 满足二叉树的所有条件,且左右子树高度不超过1(即:平衡因子不超过1)
- 平衡二叉树的最少节点:FN = F(N-1) + F(N-2) + 1(F0=0,F1=1)
- 插入结点可能不引起高度变化、也可能不在叶子节点上。
2、平衡二叉树的插入:
- 插入节点,沿着不平衡方向到根节点,找到距离根最近的三个不平衡节点,抽出来调整,其余依次插入即可。
3、平衡二叉树的删除:
- 若有左右子树:用中序前驱或中序后继替换,然后依次进行调整。
- 若为叶子节点:先删除结点,沿着不平衡方向到根节点(若不够三个则进入根节点另一个子树方向同样的找),找到距离最近的三个不平衡节点,抽出来调整,其余依次插入即可。
6、B树和B+树
1、m阶B树:
- 根结点关键字个数【1—m-1】、非根节点【m/2-1,m-1】(上取整)
- 根节点子树的个数(关键字个数+1):【2—m】、非根节点【m/2,m】(上取整)
- 非空B树的插入不一定增加树高,但删除一定会引起叶子结点的变化。
- 对任意结点,所有子树的高度都相同。
- 关键字的值类似于(类似左根右),且叶子节点不带任何信息。
2、m阶B树:度与阶数的区别
- 度为m:树中最少有一个结点的度为m。
- m阶B树:类似与二叉树,可以有一个叉也可以没有叉,只要满足B树的条件即可。【m/2-1,m-1】(上取整)
3、B树的插入和删除
- 插入前等于最大关键字插入后则分裂,删除前等于最小关键字删除后则合并。
- 插入:分裂的时候是上取整,然后放入父结点中,
- 删除:①可直接删除;②兄弟够借,先借父结点然后把兄弟还给父结点。(可左借最小,或右借最大);③若兄弟都不够借,先合并一个父结点,然后再合并左或右。
- 删除之后可能出现的合并操作,可能会使父节点下溢出(即父节点小于最小关键字结点数,然后合并父)
1、m阶B+树:
- 叶结点包含所有关键字,并以指针相连,支持顺序查找(B树不支持顺序查找)
- B+兼容顺序和随机查找,而B树只能中序遍历。
- 叶结点包含信息,非叶节点仅起索引的作用,可能会出现重复,并以lg的时间查找数据块,避免指针从头遍历这一繁琐过程,
- 树中每个结点最多有m颗子树,非叶根节点最少有两个子树,其余跟B树一样。
- B树和B+均是平衡多叉树,均支持文件索引随即检索。
7、散列表(Hash)
1、散列表:
- 建立了关键字和存储地址之间的一种直接映射关系。
- 时间复杂度为O(1),空间换时间,与元素的个数无关。
- 对于一定的元素装入一定的表长中,存储效率是一定的。
2、散列表的查找效率取决于:
- 散列函数、处理冲突的方法、装填因子。
3、装填因子a:
- a=表中的元素数 / 散列表的长度
- 平均查找长度依赖于装填因子a,而不依赖于表厂和记录数。
- a越大则装的越满,冲突的可能性越大,查找长度越长,效率越低。
1、哈希函数的构造方法:常用的散列函数
- 直接定址法:仅适用于地址集合的大小=关键字集合的大小,基本上关键字连续分布。
- 除留余数法:不大于表长的最大质数。
- 数字分析法:关键字事先知道。
- 平方取中法:事先不知道关键字且关键字不能很大。
2、 处理冲突的方法一:开放地址法
- 线性探测法:容易堆积,降低效率。
- 平方探测法:不容易堆积,但是不能探测所有单元。
- 双散列法、伪随机数法:
3、ASL成功、ASL失败:
- 成功:总比较次数 / 元素总个数
- 失败:①从当前位置找到第一个为空的地址,若是最后一个则循环到前面进行找;②只取前余数个数,且每个位置都要算上,空的位置也要算记为1;③除以余数。
4、处理冲突的方法二:链地址法
- 同义词存储在同一个线性链表中,并用一维数组存放头指针。
- 适合于经常插入和删除的情况,且ASL与散列函数有关。
3、ASL成功、ASL失败:
- 成功:(1×高度为1的个数+2×高度为2的个数+.......)/ 元素总个数
- 失败:一个头指针后面的边链表只算一次(只算最大的查找次数),所有的相加然后除以余数。