C++ 图 的延展 二叉树(四十)【第六篇】

记得上次讲:

图片

那今天我们呢就来深入地讲一下二叉树,二叉树还有很多的细节我们未讲过。

1.二叉树的储存

二叉树的存储

我们前面学会了二叉树,下面我们来看看二叉树的存储是怎样进行的吧!

C++ 图 的延展 二叉树(四十)【第六篇】_第1张图片

从二叉树的结构来看,除根结点以外的所有结点都跟 上一层 结点有直接相连的关系。

二叉树的存储

表示结点信息的结构体:

struct node {    char value;  //记录结点上的值,数据类型可做更改    node *lchild, *rchild; //记录每个结点指向下一层的左右两个孩子结点(指针类型)};
 
  

如下图中的黄色标记的结点:

黄色圆圈部分表示结点上的值;

两条带箭头的边表示结构体内指针指向的下一层结点位置。

C++ 图 的延展 二叉树(四十)【第六篇】_第2张图片

想一想: 如何连接二叉树上的所有结点呢?

现阶段我们只需要掌握基本的二叉树结点表示即可,关于二叉树的更多细节操作比较复杂,后面的阶段我们会再讲。

二叉树的存储

用结构体进行二叉树的存储比较麻烦的话,还有什么方法能方便存储一棵二叉树呢?

二叉树的 结点个数 和 层数 之间还有一种特殊的关系:

  • 每一层结点个数 最多 是上一层的结点个数的 两倍。

C++ 图 的延展 二叉树(四十)【第六篇】_第3张图片

上图中,

除最下面一层以外,每个父亲结点都有 2 个孩子结点。

每一层的结点个数都是上一层的 两倍。

这样的二叉树叫做 满二叉树。

满二叉树的存储

若对含 
n 个结点的满二叉树从上到下且从左至右进行 
1 至 n 的编号,则对满二叉树中任意一个编号为 
i 的结点有如下特性:

  1. 若 
    i=1,则该结点是二叉树的根,无双亲,否则,编号为 i/2 的结点为其双亲结点。

  2. 编号为 
    2×i 的结点是编号为 
    i 的左孩子结点。

  3. 编号为 
    2×i+1 的结点是编号为 
    i 的右孩子结点。

C++ 图 的延展 二叉树(四十)【第六篇】_第4张图片

这样的编号关系,用 数组 模拟存储的话会不会更方便?

二叉树的存储

下面我们通过两个例子来看一下,二叉树在数组中是怎样存放的,其中根结点储存在 1 号位置。

C++ 图 的延展 二叉树(四十)【第六篇】_第5张图片

上图为一棵满二叉树,它的存储为:

C++ 图 的延展 二叉树(四十)【第六篇】_第6张图片

二叉树的存储

那么对于不是满二叉树的情况:

C++ 图 的延展 二叉树(四十)【第六篇】_第7张图片

上图中是一棵正常的二叉树,他的存储为:

图片

其中: ^ 代表空(NULL)。

2.二叉树的遍历

二叉树的遍历

我们前面学会了二叉树的存储,下面我们来看看二叉树如何访问到每个结点的吧!

C++ 图 的延展 二叉树(四十)【第六篇】_第8张图片

二叉树访问每个结点一定需要按照某种 顺序 逐一访问。

二叉树常考的遍历方式有三种:

前序遍历

中序遍历

后序遍历

二叉树的前序遍历

前序遍历的 访问顺序:

  1. 根结点

  2. 左子树

  3. 右子树

前序遍历通俗的说就是从二叉树的根结点去进行遍历,当第一次到达某个结点 x 时:

  1. 访问该结点(可以输出一些结点相关的信息)。

  2. 访问 �x 的左儿子,并且继续向下递归访问,如果没有则直接进行下一步。

  3. 访问 �x 的右儿子,并且继续向下递归访问,如果没有则直接进行下一步。

  4. 返回到父亲处,如果 �x 是根,那么遍历结束。

C++ 图 的延展 二叉树(四十)【第六篇】_第9张图片

上图为一棵满二叉树,它的前序遍历过程为:

  1. 从根结点出发,第一次遇到 A,输出 A。

  2. 然后向左访问,访问 
    A 的左儿子,遇到 
    B,输出 
    B。

  3. 继续向左访问,访问 B 的左儿子,遇到 
    D,输出 
    D。

  4. 此时 
    D 为叶子结点,返回到 
    B,这是第二次访问 
    B,所以不再输出 
    B。

  5. 继而访问 B 的右儿子,遇到 E,输出 E。

  6. 此时 E 为叶子结点,返回到 
    B,这是第三次访问 
    B,所以不再输出 
    B。

  7. 退回到 
    A,以同样的方式访问 
    C、F、G。

最终输出:ABDECFG

二叉树的中序遍历

中序遍历访问顺序:

  1. 左子树

  2. 根结点

  3. 右子树

中序遍历通俗的说就是从二叉树的根结点出发,当第一次到达某个结点 
� 时:

  1. 访问 x 的左儿子,并且继续向下递归访问,如果没有则直接进行下一步。

  2. 访问该结点(可以输出一些结点相关的信息)。

  3. 访问 � 的右儿子,并且继续向下递归访问,如果没有则直接进行下一步。

  4. 返回到父亲处,如果 � 是根,那么遍历结束。

C++ 图 的延展 二叉树(四十)【第六篇】_第10张图片

上图中满二叉树的中序遍历最终输出为:DBEAFCG

二叉树的后序遍历

后序遍历访问顺序:

  1. 左子树

  2. 右子树

  3. 根结点

后序遍历可以类比前面的遍历过程来进行。

C++ 图 的延展 二叉树(四十)【第六篇】_第11张图片

最终后序遍历输出为:DEBFGCA

你可能感兴趣的:(C++,数据结构,算法)