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

一、几个概念

二叉树(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;
}
相关推荐
ULTRA??13 分钟前
插入排序算法实现(二分查找搜索版本)
c++·算法
Elias不吃糖13 分钟前
LeetCode 71:简化 Unix 路径(Simplify Path)——栈 / vector
算法·leetcode·
sheeta199816 分钟前
LeetCode 每日一题笔记 日期:2025.12.15 题目:2110.股票平滑下跌阶段的数目
笔记·算法·leetcode
智者知已应修善业7 小时前
【求中位数】2024-1-23
c语言·c++·经验分享·笔记·算法
地平线开发者8 小时前
PTQ 量化数值范围与优化
算法·自动驾驶
sali-tec8 小时前
C# 基于halcon的视觉工作流-章68 深度学习-对象检测
开发语言·算法·计算机视觉·重构·c#
测试人社区-小明8 小时前
智能弹性伸缩算法在测试环境中的实践与验证
人工智能·测试工具·算法·机器学习·金融·机器人·量子计算
罗西的思考9 小时前
【Agent】MemOS 源码笔记---(5)---记忆分类
人工智能·深度学习·算法
qq_4335545411 小时前
C++数位DP
c++·算法·图论
AshinGau12 小时前
Softmax 与 交叉熵损失
神经网络·算法