【数据结构】树与二叉树(七):二叉树的遍历(先序、中序、后序及其C语言实现)

文章目录

5.2.1 二叉树

  二叉树是一种常见的树状数据结构,它由结点的有限集合组成。一个二叉树要么是空集,被称为空二叉树,要么由一个根结点和两棵不相交的子树组成,分别称为左子树右子树。每个结点最多有两个子结点,分别称为左子结点和右子结点。
在这里插入图片描述

二叉树性质

引理5.1:二叉树中层数为i的结点至多有 2 i 2^i 2i个,其中 i ≥ 0 i \geq 0 i0

引理5.2:高度为k的二叉树中至多有 2 k + 1 − 1 2^{k+1}-1 2k+11个结点,其中 k ≥ 0 k \geq 0 k0

引理5.3:设T是由n个结点构成的二叉树,其中叶结点个数为 n 0 n_0 n0,度数为2的结点个数为 n 2 n_2 n2,则有 n 0 = n 2 + 1 n_0 = n_2 + 1 n0=n2+1

  • 详细证明过程见前文:【数据结构】树与二叉树(三):二叉树的定义、特点、性质及相关证明

满二叉树、完全二叉树定义、特点及相关证明

  • 详细证明过程见前文:【数据结构】树与二叉树(四):满二叉树、完全二叉树及其性质

5.2.2 二叉树顺序存储

  二叉树的顺序存储是指将二叉树中所有结点按层次顺序存放在一块地址连续的存储空间中,详见:
【数据结构】树与二叉树(五):二叉树的顺序存储(初始化,插入结点,获取父节点、左右子节点等)

5.2.3 二叉树链接存储

  二叉树的链接存储系指二叉树诸结点被随机存放在内存空间中,结点之间的关系用指针说明。在链式存储中,每个二叉树结点都包含三个域:数据域(Data)、左指针域(Left)和右指针域(Right),用于存储结点的信息和指向子结点的指针,详见:
【数据结构】树与二叉树(六):二叉树的链式存储

5.2.4 二叉树的遍历

  • 遍历(Traversal)是对二叉树中所有节点按照一定顺序进行访问的过程。
  • 通过遍历,可以访问树中的每个节点,并按照特定的顺序对它们进行处理。
  • 对二叉树的一次完整遍历,可给出树中结点的一种线性排序。
    • 在二叉树中,常用的遍历方式有三种:先序遍历中序遍历后序遍历
    • 这三种遍历方式都可以递归地进行,它们的区别在于节点的访问顺序
      • 在实现遍历算法时,需要考虑递归终止条件和递归调用的顺序。
    • 还可以使用迭代的方式来实现遍历算法,使用栈或队列等数据结构来辅助实现。
  • 遍历是二叉树中基础而重要的操作,它为其他许多操作提供了基础,如搜索、插入、删除等。
    在这里插入图片描述

1. 先序遍历

理论

  先序遍历(Preorder Traversal):根节点的访问顺序在左右子树之前

  • 先访问根节点;
  • 然后递归地对左子树进行先序遍历;
  • 最后递归地对右子树进行先序遍历。
  • a b d e f g c
    在这里插入图片描述

练习

在这里插入图片描述

答案见文末~

代码实现

void preOrderTraversal(struct Node* root) {
    if (root == NULL) {
        return;
    }
    // 访问根节点
    printf("%c ", root->data);
    // 递归遍历左子树
    preOrderTraversal(root->left);
    // 递归遍历右子树
    preOrderTraversal(root->right);
}

2. 中序遍历

理论

  中序遍历(Inorder Traversal):根节点的访问顺序在左右子树之间

  • 先递归地对左子树进行中序遍历,
  • 然后访问根节点,
  • 最后递归地对右子树进行中序遍历。
  • d b f e g a c
    在这里插入图片描述

练习

在这里插入图片描述

答案见文末~

代码实现

void inOrderTraversal(struct Node* root) {
    if (root == NULL) {
        return;
    }
    // 递归遍历左子树
    inOrderTraversal(root->left);
    // 访问根节点
    printf("%c ", root->data);
    // 递归遍历右子树
    inOrderTraversal(root->right);
}

3. 后序遍历

理论

  后序遍历(Postorder Traversal):根节点的访问顺序在左右子树之后

  • 先递归地对左子树进行后序遍历;
  • 然后递归地对右子树进行后序遍历;
  • 最后访问根节点。
  • d f g e b c a
    在这里插入图片描述

练习

在这里插入图片描述

答案见文末~

代码实现

void postOrderTraversal(struct Node* root) {
    if (root == NULL) {
        return;
    }
    // 递归遍历左子树
    postOrderTraversal(root->left);
    // 递归遍历右子树
    postOrderTraversal(root->right);
    // 访问根节点
    printf("%c ", root->data);
}

4. 代码整合

#include <stdio.h>
#include <stdlib.h>

// 二叉树结点的定义
struct Node {
    char data;
    struct Node* left;
    struct Node* right;
};

// 创建新结点
struct Node* createNode(char data) {
    struct Node* newNode = (struct Node*)malloc(sizeof(struct Node));
    if (newNode == NULL) {
        printf("Memory allocation failed!\n");
        exit(1);
    }
    newNode->data = data;
    newNode->left = NULL;
    newNode->right = NULL;
    return newNode;
}
// 先序遍历
void preOrderTraversal(struct Node* root) {
    if (root == NULL) {
        return;
    }
    // 访问根节点
    printf("%c ", root->data);
    // 递归遍历左子树
    preOrderTraversal(root->left);
    // 递归遍历右子树
    preOrderTraversal(root->right);
}

// 中序遍历
void inOrderTraversal(struct Node* root) {
    if (root == NULL) {
        return;
    }
    // 递归遍历左子树
    inOrderTraversal(root->left);
    // 访问根节点
    printf("%c ", root->data);
    // 递归遍历右子树
    inOrderTraversal(root->right);
}

// 后序遍历
void postOrderTraversal(struct Node* root) {
    if (root == NULL) {
        return;
    }
    // 递归遍历左子树
    postOrderTraversal(root->left);
    // 递归遍历右子树
    postOrderTraversal(root->right);
    // 访问根节点
    printf("%c ", root->data);
}
int main() {
    // 创建一棵二叉树
    struct Node* root = createNode('a');
    root->left = createNode('b');
    root->right = createNode('c');
    root->left->left = createNode('d');
    root->left->right = createNode('e');
    root->left->right->left = createNode('f');
    root->left->right->right = createNode('g');
    // 递归先序遍历二叉树
    printf("Rre-order traversal: \n");
    preOrderTraversal(root);
    printf("\n");

    // 递归中序遍历二叉树
    printf("In-order traversal: \n");
    inOrderTraversal(root);
    printf("\n");

    // 递归后序遍历二叉树
    printf("Post-order traversal: \n");
    postOrderTraversal(root);
    printf("\n");


    return 0;
}

在这里插入图片描述

5. 答案

在这里插入图片描述

  • 先序遍历
    • t1: a b d e f g c
    • t2: a b d c e f g
  • 中序遍历
    • t1: d b f e g a c
    • t2: d b c a f e g
  • 后序遍历
    • t1: d f g e b c a
    • t2: d c b f g e a

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/131339.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

leetcode(力扣) 207. 课程表1+2(图的构造与遍历,清晰思路,完整模拟)

文章目录 题目描述思路分析完整代码 题目描述 你这个学期必须选修 numCourses 门课程&#xff0c;记为 0 到 numCourses - 1 。 在选修某些课程之前需要一些先修课程。 先修课程按数组 prerequisites 给出&#xff0c;其中 prerequisites[i] [ai, bi] &#xff0c;表示如果要学…

网易云音乐未登录接口返回301

网易云音乐 NodeJS 版 API (neteasecloudmusicapi.js.org) 上面是网易云音乐的官方API接口文档 当我调用接口发送请求的时候部分接口数据是需要登录之后进行获取的&#xff0c;但是当我发送请求的时候原生js项目中的跨端问题是比较难解决的。 遇到的问题&#xff1a;跨端请求…

超详细!Linux内核内存规整详解

1.前言 伙伴系统作为内核最基础的物理页内存分配器&#xff0c;具有高效、实现逻辑简介等优点&#xff0c;其原理页也尽可能降低内存外部碎片产生&#xff0c;但依然无法杜绝碎片问题。外部碎片带来的最大影响就是内存足够&#xff0c;但是却无法满足内存分配需求&#xff0c;如…

35 字段类型不匹配 影响 使用索引?

前言 这是一个经常能够看到的问题, 又或者 经常在面试中碰到 如果 索引字段类型 不匹配, 然后 不会使用索引 这里 我们来看一下 具体的情况 测试表结构如下 CREATE TABLE tz_test (id int(11) unsigned NOT NULL AUTO_INCREMENT,field1 varchar(128) DEFAULT NULL,PRIMA…

开放领域问答机器人1

开放领域问答机器人是一种智能机器人&#xff0c;它不受限制&#xff0c;可以回答任何问题。这种机器人主要通过自然语言处理技术来理解用户的问题&#xff0c;并从大量的数据中获取相关信息&#xff0c;以提供准确的答案。它的应用领域广泛&#xff0c;包括客户服务、教育、医…

GS3661V1 3.7升压5V 3A SOT23-5封装 外置MOS 升压芯片 单节锂电升压5V 2.5-3A

GS3661V1 3.7升压5V 3A SOT23-5 外置MOS 升压芯片 单节锂电升压5V 2.5-3A

贝锐向日葵亮相云栖大会,携手无影推出全新“云桌面”功能

2023年10月31日-11月2日&#xff0c;一年一度的云栖大会如期举办&#xff0c;本届云栖大会主题为“计算&#xff0c;为了无法计算的价值”&#xff0c;国民级远程控制品牌“贝锐向日葵”亮相云栖大会&#xff0c;参与了以“云电脑”为主题的聚合话题活动。 活动现场&#xff0c…

Vue3组件

组件&#xff08;Component&#xff09;是 Vue.js 最强大的功能之一。 组件可以扩展 HTML 元素&#xff0c;封装可重用的代码。 组件系统让我们可以用独立可复用的小组件来构建大型应用&#xff0c;几乎任意类型的应用的界面都可以抽象为一个组件树&#xff1a; 每个 Vue 应用…

基于SSM的食用菌菌棒溯源系统

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;Vue 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#xff1a;是 目录…

广告算法资料汇总【建设中】

业内大佬 阿里妈妈技术 张俊林 王喆 萧瑟 朱小强 综合 付海军&#xff1a;基于互联网广告发展演变和思考&#xff08;附视频讲解PPT&#xff09; 广告算法工程师入门_广告与算法的博客-CSDN博客 广告算法学习笔记 20万、50万、100万的算法工程师&#xff0c;到底有什么区别…

Linux编辑器---vim的使用

Vim是一个高度可配置的文本编辑器&#xff0c;它是操作Linux的一款利器&#xff0c;旨在高效地创建和更改任何类型的文本。这款编辑器起源于"vi"&#xff0c;并在此基础上发展出了众多新的特性。Vim被普遍推崇为类Vi编辑器中最好的一个&#xff0c;事实上真正的劲敌来…

【算法与数据结构】131、LeetCode分割回文串

文章目录 一、题目二、解法三、完整代码 所有的LeetCode题解索引&#xff0c;可以看这篇文章——【算法和数据结构】LeetCode题解。 一、题目 二、解法 思路分析&#xff1a;本题仍然使用回溯算法的一般结构。加入了一个判断是否是回文串的函数&#xff0c;利用起始和终止索引进…

程序员的护城河:技术、创新与软实力的完美融合

作为IT行业的从业者&#xff0c;我们深知程序员在保障系统安全、数据防护以及网络稳定方面所起到的重要作用。他们是现代社会的护城河&#xff0c;用代码构筑着我们的未来。那程序员的护城河又是什么呢&#xff1f;是技术能力的深度&#xff1f;是对创新的追求&#xff1f;还是…

【深度】详细解读与评测OpenAI DevDay的最新API更新与应用

原文&#xff1a;https://www.toutiao.com/article/7299498535408665088/?log_fromd9f79b9fe2182_1699572121760 专注LLM深度应用&#xff0c;关注我不迷路 周二凌晨&#xff0c;全球无数AI科技工作者与极客们翘首以盼的首届OpenAI开发者大会上&#xff0c;仅仅四十分钟的主…

win11下安装odoo17(conda python11)

win11下安装odoo17 odoo17发行了&#xff0c;据说&#xff0c;UI做了很大改进&#xff0c;今天有空&#xff0c;体验一下 打开官方仓库&#xff1a; https://github.com/odoo/odoo 默认的版本已经变成17了 打开odoo/odoo/init.py&#xff0c;发现对python版本的要求也提高了…

Vue的vant notify组件报错Notify is not defined

解决方法&#xff1a; 原创作者&#xff1a;吴小糖 创作时间&#xff1a;2023.11.10

sCrypt 现在支持 Ordinals 了

比特币社区对 1Sat Ordinals 的接受度正在迅速增加&#xff0c;已有超过 4800 万个铭文被铸造&#xff0c;这一新创新令人兴奋不已。 尽管令人兴奋&#xff0c;但 Ordinals 铭文的工具仍然不发达&#xff0c;这使得使用 Ordinals 进行构建具有挑战性。 更具体地说&#xff0c;缺…

一文读懂RestCloud AppLink

RestCloud AppLink是什么&#xff1f; RestCloud AppLink 是一种应用程序集成解决方案&#xff0c;它提供了一套工具和技术&#xff0c;用于实现不同应用程序之间的无缝集成和交互。平台旨在解决企业中应用程序之间数据孤岛、信息孤立和业务流程不畅的问题&#xff0c;提高企业…

【数据结构】单链表之--无头单向非循环链表

前言&#xff1a;前面我们学习了动态顺序表并且模拟了它的实现&#xff0c;今天我们来进一步学习&#xff0c;来学习单链表&#xff01;一起加油各位&#xff0c;后面的路只会越来越难走需要我们一步一个脚印&#xff01; &#x1f496; 博主CSDN主页:卫卫卫的个人主页 &#x…

云计算:未来世界的超级英雄

在这个充满奇妙的时代&#xff0c;云计算被赋予了超级英雄的力量。它以其高效、可靠的数据处理能力&#xff0c;成为了推动智能科技发展的核心引擎。想象一下&#xff0c;你的智能家居设备能够通过云计算与你互动&#xff0c;根据你的需求智能调节温度、照明、音乐&#xff0c;…