数据结构-二叉树的遍历和线索二叉树

一、了解二叉树遍历

1. 先序遍历

定义:先序遍历是指在访问一个节点时,先访问该节点本身,然后再访问其左子树和右子树。

顺序

  1. 访问根节点
  2. 先序遍历左子树
  3. 先序遍历右子树

示例

假设有如下二叉树:

复制代码
      A
     / \
    B   C
   / \
  D   E

先序遍历的结果为:A, B, D, E, C

应用:先序遍历通常用于复制树结构或生成树的前缀表达式。

2. 中序遍历

定义:中序遍历是指在访问一个节点时,先访问其左子树,然后访问该节点本身,最后访问其右子树。

顺序

  1. 中序遍历左子树
  2. 访问根节点
  3. 中序遍历右子树

示例

对于同样的二叉树:

复制代码
      A
     / \
    B   C
   / \
  D   E

中序遍历的结果为:D, B, E, A, C

应用:中序遍历常用于生成树的中缀表达式,特别是在二叉搜索树中,中序遍历会得到一个有序的节点值列表。

3. 后序遍历

定义:后序遍历是指在访问一个节点时,先访问其左子树和右子树,最后访问该节点本身。

顺序

  1. 后序遍历左子树
  2. 后序遍历右子树
  3. 访问根节点

示例

对于同样的二叉树:

复制代码
      A
     / \
    B   C
   / \
  D   E

后序遍历的结果为:D, E, B, C, A

应用:后序遍历通常用于删除树的节点或计算树的大小,也常用于生成树的后缀表达式。

总结:

  • 先序遍历:根 -> 左 -> 右
  • 中序遍历:左 -> 根 -> 右
  • 后序遍历:左 -> 右 -> 根

二、二叉树遍历程序(C语言-先/中/后序遍历)

1. 链式存储结构

复制代码
// 定义二叉树节点结构体
typedef struct TreeNode {
    int data;               // 节点存储的数据
    struct TreeNode* Left;  // 指向左子节点的指针
    struct TreeNode* Right; // 指向右子节点的指针
} TreeNode, * BiTree; // 定义BiTree为TreeNode的指针类型

2. 打印节点数据

复制代码
// 打印节点数据的函数
void printf_BiTree(int data) {
    printf("%d ", data); // 打印数据并添加空格以便于输出格式
}

3. 先序遍历

复制代码
// 先序遍历函数
void PreOrder(BiTree T) {
    if (T != NULL) { // 如果节点不为空
        printf_BiTree(T->data); // 打印当前节点数据
        PreOrder(T->Left);       // 递归遍历左子树
        PreOrder(T->Right);      // 递归遍历右子树
    }
}

4. 中序遍历

复制代码
// 中序遍历函数
void InOrder(BiTree T) { // 修正函数名
    if (T != NULL) { // 如果节点不为空
        InOrder(T->Left);       // 递归遍历左子树
        printf_BiTree(T->data); // 打印当前节点数据
        InOrder(T->Right);      // 递归遍历右子树
    }
}

5. 后续遍历

复制代码
// 后序遍历函数
void PostOrder(BiTree T) { // 修正函数名
    if (T != NULL) { // 如果节点不为空
        PostOrder(T->Left);       // 递归遍历左子树
        PostOrder(T->Right);      // 递归遍历右子树
        printf_BiTree(T->data);   // 打印当前节点数据
    }
}

6. 演示案例

复制代码
// 主函数
int main() {
    // 创建树节点
    TreeNode n1 = { 1, NULL, NULL }; // 创建叶子节点1
    TreeNode n2 = { 2, NULL, NULL }; // 创建叶子节点2
    TreeNode n3 = { 3, &n1, &n2 };   // 创建根节点3,左子树为n1,右子树为n2

    // 打印先序遍历结果
    printf("PreOrder: ");
    PreOrder(&n3); // 调用先序遍历函数
    printf("\n");   // 换行

    // 打印中序遍历结果
    printf("InOrder: ");
    InOrder(&n3); // 调用中序遍历函数
    printf("\n");  // 换行

    // 打印后序遍历结果
    printf("PostOrder: ");
    PostOrder(&n3); // 调用后序遍历函数
    printf("\n");    // 换行

    return 0; // 程序结束
}

三、总代码

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


// 定义二叉树节点结构体
typedef struct TreeNode {
    int data;               // 节点存储的数据
    struct TreeNode* Left;  // 指向左子节点的指针
    struct TreeNode* Right; // 指向右子节点的指针
} TreeNode, * BiTree; // 定义BiTree为TreeNode的指针类型

// 打印节点数据的函数
void printf_BiTree(int data) {
    printf("%d ", data); // 打印数据并添加空格以便于输出格式
}

// 先序遍历函数
void PreOrder(BiTree T) {
    if (T != NULL) { // 如果节点不为空
        printf_BiTree(T->data); // 打印当前节点数据
        PreOrder(T->Left);       // 递归遍历左子树
        PreOrder(T->Right);      // 递归遍历右子树
    }
}

// 中序遍历函数
void InOrder(BiTree T) { // 修正函数名
    if (T != NULL) { // 如果节点不为空
        InOrder(T->Left);       // 递归遍历左子树
        printf_BiTree(T->data); // 打印当前节点数据
        InOrder(T->Right);      // 递归遍历右子树
    }
}

// 后序遍历函数
void PostOrder(BiTree T) { // 修正函数名
    if (T != NULL) { // 如果节点不为空
        PostOrder(T->Left);       // 递归遍历左子树
        PostOrder(T->Right);      // 递归遍历右子树
        printf_BiTree(T->data);   // 打印当前节点数据
    }
}


// 主函数
int main() {
    // 创建树节点
    TreeNode n1 = { 1, NULL, NULL }; // 创建叶子节点1
    TreeNode n2 = { 2, NULL, NULL }; // 创建叶子节点2
    TreeNode n3 = { 3, &n1, &n2 };   // 创建根节点3,左子树为n1,右子树为n2

    // 打印先序遍历结果
    printf("PreOrder: ");
    PreOrder(&n3); // 调用先序遍历函数
    printf("\n");   // 换行

    // 打印中序遍历结果
    printf("InOrder: ");
    InOrder(&n3); // 调用中序遍历函数
    printf("\n");  // 换行

    // 打印后序遍历结果
    printf("PostOrder: ");
    PostOrder(&n3); // 调用后序遍历函数
    printf("\n");    // 换行
     


    return 0; // 程序结束
}
相关推荐
SweetCode10 分钟前
裴蜀定理:整数解的奥秘
数据结构·python·线性代数·算法·机器学习
ゞ 正在缓冲99%…23 分钟前
leetcode76.最小覆盖子串
java·算法·leetcode·字符串·双指针·滑动窗口
xuanjiong23 分钟前
纯个人整理,蓝桥杯使用的算法模板day2(0-1背包问题),手打个人理解注释,超全面,且均已验证成功(附带详细手写“模拟流程图”,全网首个
算法·蓝桥杯·动态规划
惊鸿.Jh43 分钟前
【滑动窗口】3254. 长度为 K 的子数组的能量值 I
数据结构·算法·leetcode
明灯L43 分钟前
《函数基础与内存机制深度剖析:从 return 语句到各类经典编程题详解》
经验分享·python·算法·链表·经典例题
碳基学AI1 小时前
哈尔滨工业大学DeepSeek公开课:探索大模型原理、技术与应用从GPT到DeepSeek|附视频与讲义免费下载方法
大数据·人工智能·python·gpt·算法·语言模型·集成学习
补三补四1 小时前
机器学习-聚类分析算法
人工智能·深度学习·算法·机器学习
独好紫罗兰1 小时前
洛谷题单3-P5718 【深基4.例2】找最小值-python-流程图重构
开发语言·python·算法
正脉科工 CAE仿真1 小时前
基于ANSYS 概率设计和APDL编程的结构可靠性设计分析
人工智能·python·算法
爱喝热水的呀哈喽1 小时前
Java 集合 Map Stream流
数据结构