数据结构 - 树Tree

来源:互联网 发布:社交网络中文 编辑:程序博客网 时间:2024/06/02 21:48

    • 特殊二叉树
        • 满二叉树
        • 完全二叉树
        • 查找二叉树二叉排序树Binary Search TreeBinary Sort Tree
          • 性质定义
          • 查找
          • 插入
          • 删除
        • 最优二叉树哈夫曼树
          • 定义
          • 基本术语
          • 构造哈夫曼树
          • 哈弗曼编码
        • 线索二叉树
          • 定义
          • 将二叉树转化为线索二叉树
        • 二分树
        • 二叉排序树
        • 二叉搜索树
    • 二叉树的遍历

  • 二叉树在树状结构中对内存空间的利用率最高

特殊二叉树

满二叉树

  • 如果二叉树的高度为h,树的节点数为2^h-1,h>=0,则此树为满二叉树

完全二叉树

  • 如果二叉树的深度为h,所含节点节点数小于2^h-1,但其节点的编号方式如同深度为h的满二叉树一般,从左至右,由上到下的顺序一一对应

查找二叉树(二叉排序树)Binary Search Tree/Binary Sort Tree

  • 性质/定义
    • 若它的左子树非空,则左子树上所有结点的值均小于根结点的值;
    • 若它的右子树非空,则右子树上所有结点的值均大于根结点的值;
    • 左、右子树本身又各是一棵二叉排序树。
  • 查找
    • if root == target -> success
    • if root < target -> search left child
    • if root > target -> search right child
  • 插入

    分以下几种情况进行相应的处理:

    • 如果相同键值的结点已在查找二叉树中,则不再插入;
    • 如果查找二叉树为空树,则以新结点为查找二叉树;
    • 将要插入结点的键值与插入后的父结点的键值比较,就能确定新结点是父结点的左子结点,还是右子结点,并进行相应插入,新插入的结点一定是一个新添加的叶子结点。
  • 删除

    分以下几种情况进行相应的处理:

    • 若待删除的结点p是叶子结点,则直接删除该结点;
    • 若待删除的结点p只有一个子节点,则将这个子结点与待删除结点的父结点直接连接,然后删除节点p;
    • 若待删除的结点p有两个子结点,则在其左子树上,用中序遍历寻找关健值最大的结点s,用结点s的值代替结点p的值,然后删除节点s,结点s必属于上述情况之一。

最优二叉树(哈夫曼树)

  • 定义

    带全路径长度最小的树

  • 基本术语
    • 树的路径长度:是从树根到树中每一个结点的路径长度之和。在结点数目相同的二叉树中,完全二叉树的路径长度最短。
    • 结点的权:根据应用的需要给树的结点赋的权值。
    • 带权路径长度:结点到树根之间的路径长度与该结点上权的乘积,称为结点的带权路径长度。
    • 树的带权路径长度(树的代价):树中所有叶结点的带权路径长度之和,称为树的代价。
  • 构造哈夫曼树

    构造哈夫曼树

  • 哈弗曼编码

    求出哈夫曼树后,以上图为例,只需人为规定左侧为0,右侧为1,那么结点23的编码是:00;结点11的编码是:010。哈夫曼编码是一种应用广泛且非常有效的数据压缩技术,该技术一般可将数据文件压缩掉20%-90%,其压缩效率取决于被压缩文件的特征。

线索二叉树

  • 定义

    二叉树的遍历本质上是将一个复杂的非线性结构转换为线性结构,使每个结点都有了唯一前驱和后继(第一个结点无前驱,最后一个结点无后继)。对于二叉树的一个结点,查找其左右子女是方便的,其前驱后继只有在遍历中得到。为了容易找到前驱和后继,有两种方法。一是在结点结构中增加向前和向后的指针fwd和bkd,这种方法增加了存储开销,不可取;二是利用二叉树的空链指针。现将二叉树的结点结构重新定义如下:
    线索二叉树
    对于标志域规定如下:
    Lbit=0,Lchild是通常的指正;Lbit=1,Lchild是线索;
    Rbit=0,Rchild是通常的指针;Rbit=1,Rchild是线索;

  • 将二叉树转化为线索二叉树

    第一步:将将二叉树的前序遍历、中序遍历、后序遍历的顺序写下来;
    下图前序遍历顺序:A B D E H C F G I
    中序遍历:D B H E A F C G I
    后序遍历:D H E B F I G C A
    第二步:参照遍历的顺序,找到各个结点对应的前驱和后驱,如下图:
    将二叉树转化为线索二叉树
    绿色线表示前驱;红色线表示后驱。
    上面提到线索二叉树的使用就是为了方便的找到前驱和后驱,对于中序遍历,右指针为空的结点D E H F I,利用线索(红色箭头)可以直接标识出该结点的后驱;但对于右指针非空的普通的结点B、A、C、G,它的后继是右子树最左下的结点,比如B的后继结点为H,A的后继结点为F,因此,中序遍历中找后驱分为两种情况。
    后序线索二叉树找后驱可分为三种情况,第一种:根结点后序为null;
    第二种,如果一个结点为父结点的右孩子或父结点的左孩子(父结点没有右子树),他的后继就是父结点;比如C的后驱为A结点。
    第三种,如果结点是父节点的左孩子,而且父结点有右孩子,那么后继为父结点的右子树按后序遍历列出的第一个结点。比如B结点的后继结点为F结点。

二分树

  • 定义:如果一个二叉树符合每一个节点的数据都大于左子节点且小于右子节点,则这棵树便成为二分数。
  • 二叉排序树和二叉搜索树都是二分树的一种

二叉排序树

  • 规则:
    • 第一个输入的数据当做此二叉树的树根
    • 之后的数据以递归的方式与树根进行比较,小于树根则至于左子树,大于树根则至于右子树

二叉搜索树

二叉树的遍历

  • 中序遍历: left -> root -> right
  • 前序遍历: root -> left -> right
  • 后续便利: left -> right -> root
0 0