C语言数据结构系列篇二叉树的遍历

C语言数据结构系列篇:二叉树的遍历

二叉树(Binary Tree)是一种树形结构,它由一个根节点和两个子树组成,这两个子树都是二叉树,被称为左子树和右子树。二叉树有许多用途,例如用来存储有序列表或具有层级关系的信息等等。本篇将详细讲解二叉树的遍历。

二叉树的遍历

二叉树的遍历即将二叉树中的节点按照某种顺序,一次访问每一个节点。常见的二叉树遍历方式有前序遍历、中序遍历和后序遍历。下面分别对这三种遍历方式进行讲解。

前序遍历

前序遍历是指先访问当前节点的值,然后再访问左子树和右子树。换句话说,遍历顺序为 当前节点 -> 左子树 -> 右子树

前序遍历的递归算法如下:

void preorder_traversal(BinaryTree *node) {
  if (node != NULL) {
    printf("%d ", node->value);          // 1. 访问当前节点
    preorder_traversal(node->leftChild); // 2. 前序遍历左子树
    preorder_traversal(node->rightChild);// 3. 前序遍历右子树
  }
}

例如,对于下面一棵二叉树:

        1
      /   \
     2     3
    / \   / \
   4   5 6   7

按照前序遍历的顺序,遍历结果为: 1 2 4 5 3 6 7

中序遍历

中序遍历是指先访问左子树,然后访问当前节点的值,最后访问右子树。换句话说,遍历顺序为 左子树 -> 当前节点 -> 右子树

中序遍历的递归算法如下:

void inorder_traversal(BinaryTree *node) {
  if (node != NULL) {
    inorder_traversal(node->leftChild);   // 1. 中序遍历左子树
    printf("%d ", node->value);           // 2. 访问当前节点
    inorder_traversal(node->rightChild);  // 3. 中序遍历右子树
  }
}

例如,对于下面一棵二叉树:

        1
      /   \
     2     3
    / \   / \
   4   5 6   7

按照中序遍历的顺序,遍历结果为:4 2 5 1 6 3 7

后序遍历

后序遍历是指先访问左子树,然后访问右子树,最后访问当前节点的值。换句话说,遍历顺序为 左子树 -> 右子树 -> 当前节点

后序遍历的递归算法如下:

void postorder_traversal(BinaryTree *node) {
  if (node != NULL) {
    postorder_traversal(node->leftChild);   // 1. 后序遍历左子树
    postorder_traversal(node->rightChild);  // 2. 后序遍历右子树
    printf("%d ", node->value);            // 3. 访问当前节点
  }
}

例如,对于下面一棵二叉树:

        1
      /   \
     2     3
    / \   / \
   4   5 6   7

按照后序遍历的顺序,遍历结果为:4 5 2 6 7 3 1

示例

下面是一个示例程序,使用上述三种遍历方式遍历二叉树:

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

typedef struct treeNode TreeNode;
struct treeNode {
  int value;
  TreeNode *leftChild;
  TreeNode *rightChild;
};

TreeNode* new_tree_node(int value) {
  TreeNode *newNode = (TreeNode*)malloc(sizeof(TreeNode));
  newNode->value = value;
  newNode->leftChild = NULL;
  newNode->rightChild = NULL;
  return newNode;
}

void preorder_traversal(TreeNode *node) {
  if (node != NULL) {
    printf("%d ", node->value);
    preorder_traversal(node->leftChild);
    preorder_traversal(node->rightChild);
  }
}

void inorder_traversal(TreeNode *node) {
  if (node != NULL) {
    inorder_traversal(node->leftChild);
    printf("%d ", node->value);
    inorder_traversal(node->rightChild);
  }
}

void postorder_traversal(TreeNode *node) {
  if (node != NULL) {
    postorder_traversal(node->leftChild);
    postorder_traversal(node->rightChild);
    printf("%d ", node->value);
  }
}

int main() {
  TreeNode *root = new_tree_node(1);
  root->leftChild = new_tree_node(2);
  root->rightChild = new_tree_node(3);
  root->leftChild->leftChild = new_tree_node(4);
  root->leftChild->rightChild = new_tree_node(5);
  root->rightChild->leftChild = new_tree_node(6);
  root->rightChild->rightChild = new_tree_node(7);

  printf("Preorder Traversal:\n");
  preorder_traversal(root);

  printf("\nInorder Traversal:\n");
  inorder_traversal(root);

  printf("\nPostorder Traversal:\n");
  postorder_traversal(root);

  return 0;
}

运行结果:

Preorder Traversal:
1 2 4 5 3 6 7
Inorder Traversal:
4 2 5 1 6 3 7
Postorder Traversal:
4 5 2 6 7 3 1

以上就是二叉树的遍历的完整攻略。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C语言数据结构系列篇二叉树的遍历 - Python技术站

(0)
上一篇 2023年6月27日
下一篇 2023年6月27日

相关文章

  • 你知道Spring中为何不建议使用字段注入吗

    当使用Spring进行依赖注入时,有两种方式可以实现注入:构造器注入和字段注入。构造器注入是推荐的方式,而字段注入则不被推荐。下面我会详细讲解为何不建议使用字段注入的原因。 标题1:字段注入存在的问题 Spring中的字段注入会使代码紧密耦合,这是由两个方面构成的。 第一,字段注入会对代码的可测试性造成影响。由于字段注入的实现方式是在属性上直接加上注解,而不…

    other 2023年6月26日
    00
  • Windows 7下调整网卡的优先级的方法介绍

    Windows 7下调整网卡的优先级的方法介绍 1. 确认所有可用的网卡 在开始调整网卡优先级之前,我们需要先确认当前系统中可用的网卡。按下Win + R键,打开运行对话框,输入”ncpa.cpl”并回车,打开网络连接界面。在这个界面中,我们可以看到所有已安装的网络适配器。 2. 优先级调整的方法 方法一:通过命令行工具调整 打开命令提示符。按下Win + …

    other 2023年6月28日
    00
  • PHP命名空间实现自动加载引入文件

    下面将详细讲解如何使用PHP的命名空间实现自动加载引入文件。 什么是PHP命名空间 前面提到 PHP 命名空间,我们先来解释一下什么是命名空间。 命名空间是一种避免命名冲突的方法,同时也表明了代码所在的组织、公司或个人,是 PHP5.3 版本之后新增的特性。在 PHP 中,命名空间通过namespace这个关键字来声明。 实现命名空间自动加载 使用 PHP …

    other 2023年6月25日
    00
  • androidstudio中文乱码的解决方法

    以下是关于解决Android Studio中文乱码的完整攻略,包括基本知识和两个示例。 基本知识 Android Studio是一款用于开发Android应用程序的集成开发环境(IDE)。在使用Android Studio时,有时会遇到中文乱码的问题。这通常是由于编码格式不匹配或字体设置不正确导致的。解决这个问题的方法有很多种,下面介绍两种常见的方法。 示例…

    other 2023年5月7日
    00
  • 新手如何正确使用CLion之输出hello world

    新手如何正确使用CLion之输出hello world 在程序开发的过程中,输出hello world是过程中必须要进行的操作,因为它可以帮助我们初步了解程序开发环境的运行情况。本篇文章将介绍如何通过CLion来输出hello world。 前置条件 在开始操作前,需要保证以下条件已经具备: 已经安装好了CLion; 已经安装好了编译器,如:GCC。 操作步…

    其他 2023年3月28日
    00
  • Google I/O 2015谷歌开发者大会前瞻 实时地球/Android M 是啥?

    Google I/O 2015谷歌开发者大会前瞻 Google I/O是全球最大的开发者盛会之一,每年都会吸引大量的开发者和科技爱好者聚集在一起,共同研讨最新的技术和趋势。2015年的Google I/O大会将于5月28日-29日在美国加州举行,本文将对该大会进行前瞻,并解释其中几个关键技术的含义和应用领域。 实时地球 实时地球是一种新型的地理可视化技术,可…

    other 2023年6月26日
    00
  • Linux 下sftp配置之密钥方式登录详解

    Linux 下 SFTP 配置之密钥方式登录详解 本文将介绍如何在 Linux 系统中使用密钥方式登录 SFTP。 什么是密钥方式登录? 密钥方式登录是一种比传统的用户名和密码登录更加安全的方式。在密钥方式中,用户首先需要创建一对密钥(公钥和私钥),将公钥上传到服务器端,然后使用私钥进行登录。 生成密钥对 可以使用 ssh-keygen 命令来生成密钥对。该…

    other 2023年6月27日
    00
  • js数组方法扩展实现数组统计函数

    JS数组方法扩展实现数组统计函数的攻略如下: 什么是数组统计函数 数组统计函数可以用来对数组进行一些常见的统计操作,例如求和、求平均数、最大值、最小值等等。JS原生的数组方法(如forEach、map、filter、reduce等)可以完成部分数组统计操作,但并不能满足所有需求。因此,我们需要自行实现一些常见的数组统计函数来满足特定的需求。 如何扩展数组方法…

    other 2023年6月25日
    00
合作推广
合作推广
分享本页
返回顶部