本文大部分内容整理自程杰老师的《大话数据结构》


概述:

  • n个结点的有限集
  • n=0时称为空树
  • 有且只有一个根(Root)结点
  • n>1时,其余结点又可分为m个互不相交的有限集,每一个集合又是一棵树,称为根的子树

概念:

  • 度(Degree):结点拥有的子树称为结点的度,树的度取树内各结点度的最大值
  • 深度(Depth):树的最大层次称为树的深度
  • 有序树/无序树:树中结点的各子树从左往右是有次数的,不能交换的,称有序树,否则称无序树
  • 深林(Forest):m(m>0)颗互不相交的树的集合
  • 孩子(Child):结点的子树的根称为该结点的孩子
  • 双亲(Parent):相应地,该结点称为孩子的双亲
  • 兄弟(Sibling):同一个双亲的孩子互称兄弟

结点分类:

  • 叶结点(终端结点):度为0
  • 分支结点(非终端结点、内部结点):度不为0

树的存储结构

①双亲表示法:
  • 优点:找结点的Parent的时间复杂度O(1)
  • 缺点:找结点的Child,需要遍历整个树,时间复杂度高
    数据结构——树
②孩子表示法一:

所有的结点的指针域的个数都等于树的度

  • 缺点:浪费空间
    数据结构——树
②孩子表示法二:

所有的结点的指针域的个数都等于该结点的度

  • 优点:充分利用空间
  • 缺点:各结点度不一样,导致难以维护,运算上会造成时间损耗
②孩子表示法三:

把所有结点排列起来,以单链表做存储结构,指针域指向其第一个孩子结点的地址(将每个结点的所有孩子结点都分别排列起来组成链表)

  • 优点:充分利用空间,又方便维护
  • 缺点:难以找到结点的双亲结点

数据结构——树

③双亲孩子表示法:

数据结构——树


二叉树:

概述:

  • n(n≥0)各结点的有限集合
  • n=0称为空二叉树
  • 由一个根节点和两颗互相不交叉的、分别称为左子树和右子树的二叉树组成

特点:

  • 每个结点最多2棵子树
  • 左子树和右子树是有顺序的,不允许颠倒

五种基本形态:

  • 空二叉树
  • 只有根结点
  • 根结点只有左子树
  • 根结点只有右子树
  • 根结点左右子树皆有

特殊二叉树:

  • 斜树:所有结点只有左子树称左斜树,所有结点只有右子树称右斜树
  • 满二叉树:所有结点都存在左子树和右子树,所有叶都在同一层上
  • 完全二叉树:(个人解释)满二叉树从尾巴开始砍掉连续的任意结点称完全二叉树

存储结构

  • 顺序存储结构

    • 完全二叉树
      数据结构——树

    • 一般二叉树
      数据结构——树
      缺点:极端情况,如果为斜树,将会造成大量的内存空间浪费

  • 链接存储结构
    结点设计:数据结构——树

二叉树遍历:

  • 前序遍历:
    1.二叉树为空,返回空
    2.否则访问根结点,然后前序遍历左子树,然后右子树
  • 中序遍历:
    1.二叉树为空,返回空
    2.否则从根结点开始(并不是先访问根结点),然后中序遍历根结点的左子树,然后访问根结点,最后遍历右子树
  • 后序遍历:
    1.二叉树为空,返回空
    2.否则从左到右先叶子后结点的方式遍历访问左右子树,最后访问根节点
  • 层序遍历
    1.二叉树为空,返回空
    2.否则从第一层,也就是根结点开始访问,从上而下逐层遍历,同一层中,从左往右依次访问

二叉排序树(二叉查找树):

1.左子树不空,则左子树上所有结点的值均小于根结构的值
2.右子树不空,则右子树上所有结点的值均大于根结构的值
数据结构——树

  • 查找:假设欲查找数为93,首先93比62大,选右侧走,93比88大,选右侧走,93比99小,往左侧走,找到目标93,返回true(如果到叶结点扔找不到目标值,返回false)

  • 添加:假设想添加的值为55,55比62小,往左走,比58小,再往左走,比47大,往右走,比51大,往右,成为51的右孩子

  • 删除
    ①删除的是叶结点,直接删除,如37,51,73,93
    ②删除的结点只有右子树或左子树,直接让子树的根结点移动到删除结点的位置即可,如删除58,58只有左子树,直接让47接上62成为左孩子即可
    ③删除的结点既有左子树又有右子树,让左子树中值最大的结点,或右子树中值最小的结点,继承删除结点的位置,如47被删除,可以让37继承或51继承

特殊的二叉排序树——平衡二叉树(AVL树)

  • 定义:每一个结点的左子树深度和右子树的深度差最多为1
  • 相关概念
    • 平衡因子BF(Balance Factor):左子树深度减去右子树深度的值(-1,0,1)
    • 最小不平衡子树:距离插入结点最近的,且平衡因子绝对值大于1的结点为根的子树

添加:插入结点时,先检查是否会因为插入破坏了树的平衡性,如果会,找到最小不平衡子树,再保持二叉排序树特性的前提下,调整最小不平衡子树各结点的关系,使其成为新的平衡子树

假如添加的数组是a[10]={3,2,1,4,5,6,7,10,9,8}

数据结构——树数据结构——树数据结构——树数据结构——树数据结构——树

  • 基本操作原则(以下为个人描述,非专业术语):
    ①抽离点:与parent断开的点,BF绝对值为2的点
    ②左旋转就是以抽离点的右结点继承抽离点,右旋转就是以抽离点的左结点继承抽离的点
    ③旋转只看
  • 最小不平衡子树的根结点的BF
  • 根结点的子结点的BF(孙结点不看!)
    ④最小不平衡子树的根结点的BF符号如果和子结点BF的符号不一致,先旋转子结点,再旋转根结点
    ⑤如果旋转后,根结点出现了3个子结点,取深度最低的子树重新添加进树中

红黑树(追求局部平衡而非绝对平衡的伪平衡二叉树)

①每个结点要么是黑色,要么是红色
②根结点永远为黑色
③所有的叶结点都是空结点(null),并且是黑色
④每个红色结点的两个子结点都是黑色(不会存在两个相连的红色结点)
⑤从任一结点到其子树中每个叶结点的路径都包含相同数量的黑色结点(因此插入的每个结点都为红色)

相关文章: