2、树、二叉树、二叉堆、优先队列


一、树的定义

  • 树是 n(n≥0) 个节点的有限集,在任意一个非空树中, 有如下特点:
    • 有且仅有一个 特定的节点称为根节点(root node
    • 其余节点可分为 m(m>0) 个互不相交的有限集, 每一个集合本身又是一个树, 并称为根的子树
  • 树的最大层级数, 被称为树的高度或深度,下图中树的高度为 4
    在这里插入图片描述

二、二叉树(Binary Tree)

  • 二叉树的每个节点最多有 2 个孩子节点,注意:这里是最多有 2 个,也可能只有 1 个, 或者没有孩子节点
    在这里插入图片描述
  • 满二叉树:一个二叉树的所有非叶子节点都存在左右孩子, 并且所有叶子节点都在同一层级上
    在这里插入图片描述
  • 完全二叉树:跟满二叉树相比,其只需保证最后一个节点之前的节点都都存在左右孩子即可
    在这里插入图片描述
  • 二叉树的存储结构:二叉树属于逻辑结构, 它可以通过多种物理结构(eg:链表)来表达
    在这里插入图片描述
  • 二叉树的应用:查找(类似二分查找算法,复杂度 O(logn), eg:二叉搜索树)和维持相对顺序(二叉排序树)
  • 二叉树的遍历:
    • 深度优先遍历,根据根节点的遍历顺序可分为如下三种:
      • 前序遍历:根左右(根节点、 左子树、 右子树)
      • 中序遍历:左根右(左子树、根节点、 右子树)
      • 后序遍历:左右根(左子树、 右子树、根节点)
    • 广度优先遍历(层序遍历):从根节点到叶子节点的层次关系, 一层一层横向遍历各个节点(根左右)
      在这里插入图片描述
  • 用递归或栈来实现前序、 中序、 后序遍历:
    • 这 3 种遍历方式的区别, 仅仅是输出的执行位置不同: 前序遍历的输出在前, 中序遍历的输出在中间, 后序遍历的输出在最后
    • 二叉树的构建方法有很多, 这里把一个线性的链表转化成非线性的二叉树, 链表节点的顺序恰恰是二叉树前序遍历的顺序。 链表中的空值, 代表二叉树节点的左孩子或右孩子为空的情况

三、二叉堆(Binary Heap)

  • 二叉堆是一种特殊的完全二叉树, 分为最大堆和最小堆,是实现堆排序及优先队列的基础:
    • 最大堆:任何一个父节点的值, 都大于或等于它左、 右孩子节点的值,堆顶(根节点)是整个堆中的最大元素
    • 最小堆:任何一个父节点的值, 都小于或等于它左、 右孩子节点的值,堆顶(根节点)是整个堆中的最小元素
  • 二叉堆的自我调整:
    • 插入节点:插入位置是完全二叉树的最后一个位置,插入操作是单一节点的上浮,平均交换次数都是堆高度的一半, 所以时间复杂度是 O(logn)
    • 删除节点:删除的是处于堆顶的节点,删除操作是单一节点的下沉,平均交换次数都是堆高度的一半, 所以时间复杂度是 O(logn)
    • 构建二叉堆:把一个无序的完全二叉树调整为二叉堆, 本质就是让所有非叶子节点依次下沉,时间复杂度为 O(n)

四、优先队列(Priority Queue)

  • 优先队列分为最大优先队列和最小优先队列:
    • 最大优先队列:无论入队顺序如何, 当前最大的元素都会优先出队, 这是基于最大堆实现的,时间复杂度为 O(logn)
    • 最小优先队列:无论入队顺序如何, 当前最小的元素都会优先出队, 这是基于最小堆实现的,时间复杂度为 O(logn)
      在这里插入图片描述

五、参考资料

1、北大数据结构与算法
2、https://visualgo.net/zh
3、https://www.cs.usfca.edu/~galles/visualization/Algorithms.html
4、https://github.com/algorithm-visualizer/algorithm-visualizer

©️2020 CSDN 皮肤主题: 编程工作室 设计师:CSDN官方博客 返回首页