算法导论学习笔记(五):数据结构

转载请注明原作者 @yoshino,强烈要求支持TOC目录和数学公式的输入!
更新不及时,有空慢慢写吧,原文是写在Bear上粘贴来的,可能格式有点乱。
具体的工程在我的github上。


栈、队列、链表

太基本的数据结构,没什么好说的

散列表

这个比较重要,Java中有一个很重要的容器hashMap就是通过散列表实现的。
直接散列,有冲突时如何解决

  • 链接法解决冲突
算法导论学习笔记(五):数据结构_第1张图片
链接法解决冲突

开放寻址法

开放寻址法要求所有元素通过一定的计算后都放在散列表中,不使用指针,从而加快检索速度

  • 双重散列法
    公式:h(k,i) = (h1(k) + ih2(k)) mod m;
    其中 h1(k)和h2(k)都是辅助探查函数,第一次探查的目标是h1(k),后续的探查都是加上偏移量h2(k)再mod m

散列函数

好的散列函数特点:每个关键字等可能地散列到m个槽位中的任何一个,但其实在现实情况中基本不能实现。

  • 除法散列法
    公式:h(k) = k mod m;
    m尽量选择一个不太接近2的整数幂的素数,比如说2000个关键字,不成功查找次数可以容忍到3次,那么选择2000/3附近的不太接近的2的整数幂,如701
  • 乘法散列法
    公式:h(k) = ⌊m(kA mod 1)⌋;其中(kA mod 1)指取kA的小数部分,0 m选择没有什么要求,基本选择2的某个幂次就行了
  • 全域散列法
    随机地找出一组散列函数,每次随机地抽取一个函数来实现就可以了,这样即使是相同的关键值,也会得出不同的散列结果。

二叉搜索树

所谓的二叉搜索树,就是满足左子节点不大于根节点,右子节点不小于根节点的二叉树,搜索的花费是O(lgn),具体代码实现在算法导论学习笔记(四):搜索算法有实现

  • 前序遍历:根左右
  • 中序遍历:左根右
  • 后序遍历:左右根

插入z

沿着查询的路线插入相应的叶子节点

删除z

分三种情况,如下图所示

  • 若z没有子节点,直接删除,修改z的父节点即可
  • 若z只有一个子节点,用子节点替代z,修改相应的父节点
  • 若z有两个子节点,找到z的后继节点y(一定在z的右子树上),让y代替z节点,z的右子树部分成为y的右子树,z的左子树成为y的左子树
算法导论学习笔记(五):数据结构_第2张图片
二叉树删除示意图

红黑树

红黑树是一种平衡的二叉搜索树,能确保没有一条路径会比别的路径长出两倍,是满足如下性质:

  • 每个节点都是红色或者黑色的
  • 根节点是黑色的
  • 若一个节点是红色的,那么它的两个子节点都是黑色的
  • 每个叶节点(NIL)是黑色的
  • 对于每个节点,到其叶节点的简单路径中包含相同数目的黑色节点
    一个包含n个节点的红黑树其高度至少为2lg(n+1),下面的截图基本都是出自算法导论的内容

旋转

算法导论学习笔记(五):数据结构_第3张图片
红黑树旋转1

算法导论学习笔记(五):数据结构_第4张图片
红黑树旋转2

插入

算法导论学习笔记(五):数据结构_第5张图片
红黑树插入

删除

算法导论学习笔记(五):数据结构_第6张图片
红黑树删除

你可能感兴趣的:(算法导论学习笔记(五):数据结构)