扩展二叉树前序遍历序列构建二叉树(图解)

一、几个概念

二叉树(binary tree):是 n(n >= 0)个结点(每个结点最多只有2棵子树)的有限集合,该集合可为空集(称为空二叉树),或由一个根节点和两颗互不相交的,称为根节点的左子树和右子树的二叉树组成。

扩展二叉树:将二叉树中的每个结点的空子结点用一个虚拟结点表示,其值为一特定的值,比如"#",这样每个结点都有两个子结点,这种处理后的二叉树为原二叉树的扩展树。扩展二叉树就可以做到一个遍历序列确定一颗二叉树。

例如:图1为一颗二叉树,图2为这颗二叉树的扩展二叉树

前序遍历二叉树 :先访问根结点,然后遍历左子树,最后遍历右子树

所以,图1这颗二叉树的前序遍历顺序为:ABDEGCF

这颗二叉树的扩展二叉树前序遍历序列为:ABD##E#G##CF###

二叉链表:是二叉树的一种链式存储结构,其中每个结点包含三个字段:一个数据字段(data)和两个指针字段(lchild、rchild),分别指向该结点的左孩子和右孩子。如果某个结点没有左孩子或右孩子,那么对应的指针字段为NULL。

用 C 语言可以表述为:

cpp 复制代码
typedef struct binary_node {
    char data;
    struct binary_node *lchild, *rchild;
}binary_tree;

二、算法思路

扩展二叉树前序遍历序列创建二叉树过程:

(1)如果该结点为虚拟结点(即值 = '#'),则该结点为空

(2)如果该结点存在,则创建该结点,并把值赋给 data 字段,然后创建左子树,最后创建右子树

所以,这是一个递归的过程。

那么对于图2的扩展二叉树前序遍历序列:ABD##E#G##CF###

调用创建二叉树函数图解整个创建二叉树过程为:

(1)调用创建二叉树函数,因为根结点的值为A,则创建该节点,并赋值该节点的 data = 'A'

(2)调用创建二叉树函数创建A结点的左子树,因为该结点的值为B,则创建该结点,并赋值该结点的 data = 'B'

(3)调用创建二叉树函数创建B结点的左子树,因为该结点的值为D,则创建该结点,并赋值该结点的 data = 'D'

(4)调用创建二叉树函数创建D结点的左子树,因为该结点的值为#,则该结点为空,并赋值 lchild = NULL,然后,栈顶的 create_binary_tree 函数执行完毕,从栈顶弹出

(5)调用创建二叉树函数创建D结点的右子树,因为该结点的值为#,则该结点为空,并赋值 rchild = NULL,然后,栈顶的 create_binary_tree 函数执行完毕,从栈顶弹出

(6)此时创建结点D的 create_binary_tree 函数访问结点D和创建D结点的左子树、右子树逻辑都已执行完毕,从栈顶弹出,然后,执行调用 create_binary_tree 函数创建结点B的右子树,因为该结点的值为E,则创建该结点,并赋值该结点的 data = 'E'

(7)调用创建二叉树函数创建E结点的左子树,因为该结点的值为#,则该结点为空,并赋值 lchild = NULL,然后,栈顶的 create_binary_tree 函数执行完毕,从栈顶弹出

(8)调用创建二叉树函数创建E结点的右子树,因为该结点的值为G,则创建该结点,并赋值该结点的 data = 'G'

(9)调用创建二叉树函数创建G结点的左子树,因为该结点的值为#,则该结点为空,并赋值 lchild = NULL,然后,栈顶的 create_binary_tree 函数执行完毕,从栈顶弹出

(10)调用创建二叉树函数创建G结点的右子树,因为该结点的值为#,则该结点为空,并赋值 rchild = NULL,然后,栈顶的 create_binary_tree 函数执行完毕,从栈顶弹出

(11)此时创建结点G的 create_binary_tree 函数访问结点G和创建G结点的左子树、右子树逻辑都已执行完毕,从栈顶弹出。

(12)此时创建结点E的 create_binary_tree 函数访问结点E和创建E结点的左子树、右子树逻辑都已执行完毕,从栈顶弹出。

(13)此时创建结点B的 create_binary_tree 函数访问结点B和创建B结点的左子树、右子树逻辑都已执行完毕,从栈顶弹出。

(14)调用创建二叉树函数创建A结点的右子树,因为该结点的值为C,则创建该结点,并赋值该结点的 data = 'C'

(15)调用创建二叉树函数创建C结点的左子树,因为该结点的值为F,则创建该结点,并赋值该结点的 data = 'F'

(16)调用创建二叉树函数创建F结点的左子树,因为该结点的值为#,则该结点为空,并赋值 lchild = NULL,然后,栈顶的 create_binary_tree 函数执行完毕,从栈顶弹出

(16)调用创建二叉树函数创建F结点的右子树,因为该结点的值为#,则该结点为空,并赋值 rchild = NULL,然后,栈顶的 create_binary_tree 函数执行完毕,从栈顶弹出

(17)此时创建结点F的 create_binary_tree 函数访问结点F和创建F结点的左子树、右子树逻辑都已执行完毕,从栈顶弹出。

(18)调用创建二叉树函数创建C结点的右子树,因为该结点的值为#,则该结点为空,并赋值 rchild = NULL,然后,栈顶的 create_binary_tree 函数执行完毕,从栈顶弹出

(19)此时创建结点C的 create_binary_tree 函数访问结点C和创建C结点的左子树、右子树逻辑都已执行完毕,从栈顶弹出。

(20)此时创建结点A的 create_binary_tree 函数访问结点A和创建A结点的左子树、右子树逻辑都已执行完毕,从栈顶弹出。至此,调用 create_binary_tree 函数创建二叉树函数逻辑都已执行完毕,整个函数返回,我们成功的用二叉树的扩展二叉树前序遍历序列构建二叉树如下所示

三、实现代码

cpp 复制代码
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

typedef struct binary_node {
    char data;
    struct binary_node *lchild, *rchild;
}binary_tree;

//前序遍历扩展二叉树
char *g_str = "ABD##E#G##CF###";
int g_index = 0;

void create_binary_tree(binary_tree **T) {
    if (strlen(g_str) == 0)
        return;

    if (g_str[g_index] == '#') {
        T = NULL;
        ++g_index;
    }
    else {
        *T = malloc(sizeof(**T));
        (*T)->data = g_str[g_index];
        (*T)->lchild = NULL;
        (*T)->rchild = NULL;
        ++g_index;

        create_binary_tree(&(*T)->lchild);
        create_binary_tree(&(*T)->rchild);
    }
}

void visit_node(binary_tree *T) {
    printf("%c\n", T->data);
}

void pre_order_tree(binary_tree *T) {
    if (!T)
        return;

    visit_node(T);
    pre_order_tree(T->lchild);
    pre_order_tree(T->rchild);
}

int main(int argc, char *argv[]) {
    binary_tree *T = NULL;
    create_binary_tree(&T);
    pre_order_tree(T);

    return 0;
}
相关推荐
徐小夕5 分钟前
花了3个月,我们做了一款 AI 版的“飞书文档”
前端·算法·github
Robert--cao12 分钟前
移动底盘与机械臂联合规划:开源算法与工程实现
算法
小豆庄1 小时前
Mac 上给视频人脸打码:本地工具的依赖、追踪与推理管线
算法·视觉检测·视频·敏捷流程·纹理贴图
星夜离尘561 小时前
MATLAB 工程实验:从相邻块均值手写重叠 Allan 偏差,数清有效项
算法·matlab·均值算法
careathers2 小时前
【数据结构】从堆到 PriorityQueue:手写一个优先级队列
数据结构
y1su3 小时前
Leetcode 字符串模板
java·数据结构·算法·leetcode·职场和发展·动态规划
residual_fan4 小时前
船用柴油机动态机动工况故障诊断:控制感知仿射网络(CAAN)的技术实现
人工智能·算法·数据挖掘·数据分析
其实防守也摸鱼4 小时前
Cylab在线靶场——CTF中的通用技能
linux·数据库·学习·算法·靶场·ctf·学习网络安全
蓝悦无人机5 小时前
《Planning algorithms》读书笔记——第8章 反馈运动规划
算法·读书笔记·反馈运动规划
RaaS1005 小时前
Agent Skills 进了 Linux Foundation:2.8 亿次安装,但装 skill 还没有安全规范
人工智能·算法·架构