树的简单理解

简介

树是一种树是一种非线性数据结构,所谓非线性数据结构,是指可以元素之间的关系可以一对多或多对一,多对多的数据结构。树是一种典型的非线性数据结构,树是n(n>=0)个节点的集合,n=0时被称为空树,对于一颗非空树,有且只有一个根节点,其他子节点的集合称为根节点的子树。子树是不相交的。
根据子节点数量可分为 「二叉树」 和 「多叉树」,最顶层的节点称为「根节点 root」。以二叉树为例,每个节点包含三个成员变量:「值 val」、「左子节点 left」、「右子节点 right」 。
在这里插入图片描述
#常用术语的理解
结点的度:即结点拥有的子树数量,如上图中D的度为3,B的度为1。
叶结点:也叫终端结点,指度为0的结点,如上图中的G、H、J;
分支结点:或非终端结点,度不为0的结点。
树的度:指树内各结点的度的最大值。
结点的孩子:结点的子树
结点的双亲:相对于孩子来说的
结点的兄弟:同一个双亲的孩子
结点的祖先:从根节点到该结点的所有结点,对于H来说,D,B,A都是它祖先,反之为结点的子孙

结点的层次:从根开始,每一层关系为一层
树的深度或高度:树中结点的最大层次
在这里插入图片描述
有序树:结点的各子树是有次序的,不能互换的树,反之为无序树
森林:m棵互不相交的树的集合

树存储结构的实现

对于一棵树要实现的基本操作包括

//        构造空树tree
        initTree();
        //销毁树
        destoryTree();
//        创造树
        creatTree();
        //清空树
        clear();
        //判空
        isEmpty();
        //返回树的深度
        depth();
        //返回树的根节点
        root();
        //返回树的某个结点值
        value(T e);
        //给某个结点赋值
        assign(T e,value);
        //返回双亲
        parent(T e);
        //返回左孩子
        leftChild(T e);
        //返回右兄弟,如果存在
        rightSibling(T e);
        //插入结点
        insert(T e);
        //删除子树
        delete(T e);

对于这种非线性数据结构,使用单一的顺序存储和链式存储都有一些麻烦。但对于树,有三种不同的表示法:双亲表示法,孩子表示法,孩子兄弟表示法。
树的表示方法
双亲表示法
对于非根节点的每个结点,不一定有孩子,但一定有双亲。
因此对于每一个结点可以以这种方式表示,一个数据域表示数据,一个指针域表示双亲。然后用数组存储结点作为结点集。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

这种方式可以很快找到parent,当parent为-1时表示根节点。
缺点也很明显,寻找子节点需要遍历整个结点集。解决这个问题可以添加一个最左孩子指针域。但还是有些许麻烦。

孩子表示法
树由结点组成,但其实树也可以由多个子树组成。
孩子表示法的具体内容为:把每个结点的孩子结点排列起来,以单链表存储,叶子结点的链表为空,然后将每个链表的头指针存放进一个一维数组。
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
这种结构对于要查找结点的孩子,或者找结点的兄弟,很方便,只需查找数组中的相应结点链表,遍历数组也很方便。
缺点是找双亲不方便。解决这个问题可以给数组中的头节点加一个parent域。
在这里插入图片描述
孩子兄弟表示法
对于树来说,结点的最左孩子和结点的右边兄弟如果存在就是唯一的,因此对于结点的设计可以是两个指针域表示最左孩子和右兄弟。
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
这种表示方法依旧是找孩子容易,找双亲难,但它的最大优点是把树变成了二叉树。

二叉树

基本定义

二叉树是n个有限元素的集合,该集合或者为空、或者由一个称为根(root)的元素及两个不相交的、被分别称为左子树和右子树的二叉树组成,是有序树。当集合为空时,称该二叉树为空二叉树。
在这里插入图片描述
五种基本形态:空二叉树、只有一个根节点、根节点只有左子树、根节点只有右子树、根节点既有左子树也有右子树。
特点:
每个结点最多有两颗子树。即度最大为2;
左子树和右子树是有顺序的,且次序不能颠倒;
即使只有一棵子树,也要区分左右子树。

特殊二叉树
1、斜树
所有结点只有左子树或只有右子树,称为左斜树和右斜树。
2、满二叉树
所有分支节点都存在左子树和右子树,所有叶子结点都在同一层上。在这里插入图片描述
要求是叶子只能在最底层,非叶子结点的度一定是2,在所有同深度的二叉树中,满二叉树是结点和叶子最多的二叉树。
3、完全二叉树
深度为k,有n个结点的二叉树当且仅当其每一个结点都与深度为k的满二叉树中编号从1到n的结点一一对应时,称为完全二叉树。在这里插入图片描述

特点是
叶子结点只可能出现在层序最大的两层上;即某个结点的左分支下子孙的最大层序与右分支下子孙的最大层序相等或大1;
最下层的叶子一定是从左往右连续的;
如果结点度为1,一定是左子树;
同样结点数的二叉树,完全二叉树的深度最小。

性质

1、在完全二叉树的第i层上至多只有2i-1个结点
2、深度为k的完全二叉树至多只有2k-1个结点;
3、对任何一颗完全二叉树,终端结点树为n0 =度为2的结点数n2+1.
4、具有n个结点的完全二叉树的深度为[log2n]+1;
5、若对一棵有n个节点的完全二叉树进行顺序编号(1≤i≤n),那么,对于编号为i(i≥1)的节点:
当i=1时,该节点为根,它无双亲节点
当i>1时,该节点的双亲节点的编号为i/2
若2i≤n,则有编号为2i的左节点,否则没有左节点
若2i+1≤n,则有编号为2i+1的右节点,否则没有右节点。

二叉树的树实现

顺序存储:用一维数组存储二叉树的结点,并且数组的下标要体现出结点间的关系。
在这里插入图片描述
在这里插入图片描述
这个编号是对应满二叉树的,所以很容易造成空间浪费,即这种情况:
在这里插入图片描述

链式存储:二叉树每个结点最多有两个孩子,所以结点可以设计成一个数据域两个孩子域。
在这里插入图片描述在这里插入图片描述

在这里插入图片描述
缺点是找双亲。

二叉树的遍历

二叉树的遍历有四种,给出二叉树
在这里插入图片描述

前序遍历:根左右,即先访问根节点在访问左右子树,对上遍历结果为ABDGHCEIF;
中序遍历:左根右,先访问根节点左子树,再访问根结点,最后访问根节点右子树,遍历结果GDHBAEICF;
后序遍历:左右根,先访问左右子树,在访问根节点,访问结果GHDBIEFCA;
层序遍历:一层一层的从左往右访问,访问结果ABCDEFGHI;


遍历的实现:树的遍历一般采用递归实现。 对于遍历结果:已知前序遍历结果和中序遍历结果可以唯一的确定一颗二叉树,已知后续遍历和中序遍历结果,也可以确定唯一的二叉树。

Guess you like

Origin blog.csdn.net/qq_44830792/article/details/110085225