极客讲堂 - 数据结构与算法之美 - 哈希算法,二叉树基础,红黑树,递归树,堆和堆排序,堆的应用,图的表示

21 | 哈希算法(上):如何防止数据库中的用户信息被脱库?

1. 哈希算法要满足什么条件?

(1) 从哈希值不能反向推导出原始数据

(2) 原始数据只修改了一个 Bit,最后得到的哈希值也不相同

(3) 散列冲突的概率要很小

(4) 哈希算法的执行效率要尽量高效,针对较长的文本,也能快速地计算出哈希值。

2. 哈希算法的七个应用

(1) 安全加密,比如:

    MD5 消息摘要算法,SHA 安全散列算法,DES 数据加密标准, AES 高级加密标准

(2) 唯一标识,比如:

    生成图片的唯一标识。从图片的二进制码串开头取 100 个字节,中间取 100 个字节,最后再取 100 个字节,然后将这 300 个字节放到一块,通过哈希算法(比如 MD5),得到一个哈希字符串,用它作为图片的唯一标识.

(3) 数据校验

   通过相同的哈希算法,对下载好的文件块逐一求哈希值,然后跟种子文件中保存的哈希值比对。

(4) 散列函数

    为了将一堆数据实现平均分布,以及高效率。

(5) 负载均衡 (6) 数据分片 (7) 分布式存储  : 下一节讲。

3. 如何防止数据库中的用户信息被脱库?、

(1) 通过哈希算法,对用户密码进行加密之后再存储

(2) 引入一个盐(salt),跟用户的密码组合在一起,增加密码的复杂度

22 | 哈希算法(下):哈希算法在分布式系统中有哪些应用?

1. 负载均衡

     利用哈希算法替代映射表,可以实现一个会话粘滞的负载均衡策略。(同一个客户端上,在一次会话中的所有请求都路由到同一个服务器上)

2. 数据分片

    通过哈希算法对处理的海量数据进行分片,多机分布式处理,可以突破单机资源的限制。

3. 分布式存储

    利用一致性哈希算法,可以解决缓存等分布式系统的扩容、缩容导致数据大量搬移的难题。

    具体说明查看 404,您访问的页面已经不存在!

https://www.cnblogs.com/moonandstar08/p/5405991.html

23 | 二叉树基础(上)

1. 概念

(1) 满二叉树: 除了叶子节点之外,每个节点都有左右两个子节点。

(2) 完全二叉树:叶子节点都在最底下两层,最后一层的叶子节点都靠左,并且除了最后一层,其他层的节点个数都要达到最大。

(3) 节点的高度:节点到叶子节点的最长路径(边的数目)

(4) 节点的深度:根节点到这个节点所经历的边的个数

(5) 节点的层数:节点的深度+1

(6) 树的高度:根节点的高度

2. 存储二叉树的方法,包括 链式存储法 和 顺序存储法。

(1) 链式存储法

     节点有三个字段,一个存储数据,另外两个是指向左右子节点的指针。

     大部分二叉树代码都是通过这种结构来实现的。

(2) 顺序存储法

    根节点下标为1,左节点下标为2,右节点下标为3,以此类推。

    节点 X 存储在数组中下标为 i 的位置

    下标为 2 * i 就是左子节点

    下标为 2 * i + 1 就是右子节点

    下标为 i/2 的就是它的父节点

    下标为 0 的存储位置不使用,i从1开始

3. 二叉树的遍历

(1) 前序遍历 : 中左右

(2) 中序遍历 : 左中右

(3) 后序遍历 : 左右中

24 | 二叉树基础(下)

1. 二叉查找树要求定义:

        树中的任意一个节点,其左子树中的每个节点的值,都要小于这个节点的值,而右子树节点的值都大于这个节点的值。

2. 查找:

       从根节点开始,要查找的值比根节点小的话,继续查左节点;要查找的值比根节点大的话,继续查右节点。

3. 插入:

       新插入的数据是在叶子节点上的,所以不用考虑太多,遍历下去插入就行。

4. 删除:

       分三种情况来处理

      (1)  要删除的节点没有子节点的话,只需将其父节点指向它的指针置为null

      (2)  有一个子节点,将父节点指向它指针改为指向这个唯一子节点。

      (3)  有两个子节点,将右子树中最小的节点,替换到要删除的节点上。

5. 重复数据的二叉查找树

    有重复数据的话,可以两种方式处理:

(1) 链表的方式,把值相同的数据都存储在同一个节点上。

(2) 新插入的数据当作大于来处理.

6. 时间复杂度:

     跟树的高度成正比,也就是 O(height)

7. 二叉查找树相比散列表的优势:

(1) 输出有序数据: 散列表的数据是无序的,二叉查找树,只需中序遍历就能输出有序数据。

(2) 扩容耗时: 散列表扩容耗时更大。

(3) 复杂程度: 散列表复杂一点,需要考虑散列函数,冲突情况更多。

 附:

散列表:插入删除查找都是O(1), 是最常用的,但其缺点是不能顺序遍历以及扩容缩容的性能损耗。适用于那些不需要顺序遍历,数据更新不那么频繁的。

跳表:插入删除查找都是O(logn), 并且能顺序遍历。缺点是空间复杂度O(n)。适用于不那么在意内存空间的,其顺序遍历和区间查找非常方便。

红黑树:插入删除查找都是O(logn), 中序遍历即是顺序遍历,稳定。缺点是难以实现,去查找不方便。其实跳表更佳,但红黑树已经用于很多地方了。

25 | 红黑树(上)

1. 平衡二叉树的定义:

    任意一个节点的左右子树的高度相差不能大于 1。

2. 平衡二叉树的价值:

    不会出现左子树很高,右子树很矮的情况,插入、删除、查找的操作效率比较高和稳定。

3. 红黑树的定义:

    不严格的近似平衡二叉查找树。包含两个意义:

(1) 不严格: 并不完全符合平衡二叉树的定义。

(2) 近似平衡: 性能不会退化得太严重。

4. 红黑树的要求:

(1) 根节点是黑色的

(2) 叶子节点都是黑色的空节点,不存储数据.

(3) 相邻两层的节点不能同时为红色,即:红色节点被黑色节点隔开

(4) 每个节点,从该节点到达其可达叶子节点的所有路径,都包含相同数目的黑色节点

26 | 红黑树(下)

      暂时略过

27 | 递归树

 1. 借助递归树来分析算法时间复杂度的原因:

(1) 递归树每一层操作消耗的时间总和是一样的

(2) 树的高度 h,乘以每一层的时间消耗 n,就可以得到总的时间复杂度O(n∗h)

2. 以下三个例子可以使用递归树的方式算时间复杂度:

(1) 快速排序

(2) 斐波那契数列

(3) 数据集的 全排列 操作

28 | 堆和堆排序

1. 堆的定义:

(1) 是一个完全二叉树

(2) 每一个节点的值都必须大于等于(或小于等于)其子树中每个节点的值

(3) 大于等于子节点的叫大顶堆,小于等于子节点的叫小顶堆。

2. 堆的两个操作: 插入元素 和 删除堆顶元素。  操作完后还要做调整保持堆的特性,叫做“堆化”

(1) 插入元素:

    在最后位置插入元素,从下往上做比较和替换操作。

(2) 删除堆顶元素:

    删除堆顶元素后,把最后一个元素放到堆顶位置。然后针对堆顶做堆化。

3. 堆排序的操作分两步: 建堆  和 排序

(1) 建堆:

     直接把数组视为一个堆(完全二叉树的规则),从数组的后面往前,找第一个非叶子结点,向下做“堆化”。重复直至第一个结点,就完成了建堆。

(2) 排序:

     完成建堆后,根节点就是最大的结点,直接和数组最后元素替换(正在做从小到大的排序),然后对剩下的n-1个结点做堆化(也就是最大结点脱离堆)。重复直至只剩下标为 1 的一个元素,排序工作就完成了。

4. 堆排序没有快速排序好的原因:

(1) 快速排序顺序访问数据,对CPU缓存友好。但堆排序不是。

(2) 堆排序数据交换次数更多。因为建堆的过程会打乱数据原有的相对先后顺序,导致原数据的有序度降低。

5. 堆排序比快速排序好的地方:

    堆时间复杂度比较固定,O(N*log2N)

    快速排序平均情况下是O(N*log2N) ,最坏情况下是O(N平方)

6. 优先级队列定义

    队列具有先进先出的特性,而优先级队列是按照优先级来进行处理。要选出优先级最高的元素则可以借助堆来完成。

7. 利用优先队列(即大或小顶堆)自动调整顺序的步骤:

(1) 将n个数组的第一个元素构建优先队列(小顶堆)

(2) 重复下列步骤n*m次:

     a. 每次从堆中取出最小元素(堆顶元素),并将其存入输出数组中

     b. 用堆顶元素所在数组的下一元素将堆顶元素替换掉

     c. 如果数组中元素被取光了,将堆顶元素替换为无穷大。每次替换堆顶元素后,重新调整堆

29 | 堆的应用

1. 优先级队列,具体例子:高性能定时器

     把任务按照执行时间,存储在优先级队列中。最优先的先执行,把计算它的执行时间与当前时间的差值。然后就可以根据这个差值作为执行下个任务的等待时间,不需要每秒轮询任务表。

2. 求 Top K:

    一直维护一个 K 大小的小顶堆,需要查询当前的前 K 大数据,可以立刻返回

3. 求中位数:

    把数据队列用两个堆来维护,分成大顶堆和小顶堆。

    逐个数据建堆的时候,持续调整和保证两个堆的数目相同或者相差1,并且保证一个是大根堆一个是小根堆。

    大顶堆或小顶堆的头部就是中位数。

4. 求99% 响应时间

    把数据根据响应时间,建成两个堆(大顶堆和小顶堆)。大根堆堆顶就是排99%的响应时间值。

    插入数据时,值比大根堆顶小的,就放大根堆(这是时间小于第99%的)。否则放小根堆。

5. 取到热门榜 Top 10 的搜索关键词(10 亿个)

    把10亿个词求hash值,放到散列表中。散列表就存储了不重复的关键词和出现次数。

    再构建大小为10的大顶堆。 获得结果

30 | 图的表示:如何存储微博、微信等社交网络中的好友关系?

1. 图相关概念的定义:

无向图、有向图、带权无向图,邻接矩阵存储法,如下:

邻接表如下:

2. 邻接矩阵存储法优劣点:

     优点:查询效率高,方便矩阵运算

     缺点:比较浪费空间

3.  邻接表

     优点:节省存储空间,

     缺点:链表不方便查找,查询效率没有邻接矩阵存储方式高。但可以把链表改为二叉查找树、跳表、散列表来改进。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值