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日

相关文章

  • vue3setup函数参数

    vue3 setup 函数参数 在 Vue 3 中,我们可以使用新的 setup 函数来代替之前的 created、mounted、updated、destroyed 等钩子函数。setup 函数是一个新的组件选项,在组件被创建时执行。 setup 函数接受两个参数:props 和 context。 props 参数 props 参数接收当前组件接收的属性值…

    其他 2023年3月28日
    00
  • vue项目配置env的方法步骤

    Vue项目配置.env文件主要是为了在开发和生产阶段,动态地管理不同的环境变量。比如开发人员在开发阶段,需要连接到本地开发的服务器,而在生产环境下则需要连接到生产服务器。 下面是Vue项目配置.env的步骤: 在项目根目录下,创建.env文件和.env.development文件和.env.production文件。 在.env.development和.e…

    other 2023年6月27日
    00
  • java中进程与线程_三种实现方式总结(必看篇)

    请允许我对此进行详细讲解。 Java中进程与线程 – 三种实现方式总结(必看篇) 前言 进程与线程是多任务编程中非常重要的概念,在Java中也有多种实现方式。本篇文章将介绍进程与线程的基本概念,并详细介绍三种Java实现方式。 进程与线程的基本概念 进程 进程是指一个程序在运行时的状态,包括程序计数器、内存、CPU寄存器等,是操作系统资源分配的基本单位。 线…

    other 2023年6月27日
    00
  • spring+rabbitmq+stomp搭建websocket消息推送(非springbo…

    Spring + RabbitMQ + Stomp 搭建 WebSocket 消息推送(非 Spring Boot 版本) WebSocket 是一项在 Web 开发中非常重要的技术,它允许服务器和客户端之间实时、双向通信。在实际开发过程中,我们通常需要使用一些消息队列来实现后台消息推送系统,而 RabbitMQ 是一个非常优秀的消息队列实现。本文将介绍如何…

    其他 2023年3月28日
    00
  • Scala之Object的具体使用(小结)

    下面是详细讲解“Scala之Object的具体使用(小结)”的完整攻略: 1. Object的介绍 在Scala中,Object是一种特殊的class,它只有一个单例实例。我们可以把Object看成是一些静态的方法和属性的集合,这些方法和属性可以通过Object访问,而不需要对Object进行实例化操作。因此,Object可以看成是Scala中的静态类。 2…

    other 2023年6月26日
    00
  • linux vi命令知识点用法总结

    Linux VI命令知识点用法总结 简介 VI是Linux操作系统中最基本、最经典的文本编辑器之一,也是程序员必须熟练掌握的操作工具之一。本文将详细讲解VI命令的知识点用法,涵盖VI的基本操作、光标移动、插入与修改、删除与撤销、查找与替换、保存与退出等方面。 基本操作 VI命令是在Linux终端中运行的,要创建一个新文件或打开一个已经存在的文件,需要在终端中…

    other 2023年6月26日
    00
  • ios基础-uiscrollview

    以下是“iOS基础-UIScrollView的完整攻略”的详细讲解,过程中包含两个示例说明的标准Markdown格式文本: iOS基础-UIScrollView的完整攻略 UIScrollView是iOS中一个常用的控件,可以实现滚动视图的功能。本文将介绍UIScrollView的基本用法和常见属性。 1. 创建UIScrollView 我们可以使用以下代码…

    other 2023年5月10日
    00
  • ehcart设置雷达图尺寸

    以下是ECharts设置雷达图尺寸的完整攻略: ECharts设置雷达图尺寸 ECharts是一款开源的JavaScript图表库,可以用于创建各种类型的交互式图表。以下是设置雷达图尺寸的步骤: 创建雷达图。 在ECharts中,您可以使用radar组件创建雷达图。以下是一个基本的雷达图示例: javascript option = { radar: { i…

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