C语言二叉树常见操作详解【前序,中序,后序,层次遍历及非递归查找,统计个数,比较,求深度】

yizhihongxing

C语言二叉树常见操作详解

什么是二叉树

二叉树是一种重要的数据结构,它由节点组成,每个节点最多有两个子节点,左子节点和右子节点。

二叉树具有以下性质:

  1. 每个节点最多有两个子节点。
  2. 左子节点的值小于父节点的值。
  3. 右子节点的值大于父节点的值。
  4. 左右子树都是二叉树。

二叉树的基本操作

1.创建一个二叉树

使用递归的方式来创建一个二叉树,每次创建节点时,递归创建左右子树。以下是一个示例代码:

typedef struct TreeNode{
    int data;
    struct TreeNode* left;
    struct TreeNode* right;
}TreeNode;

TreeNode* createBinaryTree(){
    int data;
    scanf("%d", &data);
    if(data == -1) {
        return NULL;
    }
    TreeNode* root = (TreeNode*)malloc(sizeof(TreeNode));
    root->data = data;
    root->left = createBinaryTree();
    root->right = createBinaryTree();
    return root;
}

使用外部数据输入的方式来创建二叉树,当输入 -1 时,代表该节点为空。

2.前序遍历二叉树

前序遍历的顺序是:先访问根节点,再遍历左子树和右子树。以下是一个示例代码:

void preOrderTraverse(TreeNode* root){
    if(root!=NULL) {
        printf("%d ",root->data);
        preOrderTraverse(root->left);
        preOrderTraverse(root->right);
    }
}

例如,对于下图所示的二叉树:

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

它的前序遍历结果为: 1 2 4 5 3 6 7

3.中序遍历二叉树

中序遍历的顺序是:先遍历左子树,再访问根节点,最后遍历右子树。以下是一个示例代码:

void inOrderTraverse(TreeNode* root){
    if(root!=NULL) {
        inOrderTraverse(root->left);
        printf("%d ",root->data);
        inOrderTraverse(root->right);
    }
}

例如,对于下图所示的二叉树:

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

它的中序遍历结果为: 4 2 5 1 6 3 7

4.后序遍历二叉树

后序遍历的顺序是:先遍历左子树,再遍历右子树,最后访问根节点。以下是一个示例代码:

void postOrderTraverse(TreeNode* root){
    if(root!=NULL) {
        postOrderTraverse(root->left);
        postOrderTraverse(root->right);
        printf("%d ",root->data);
    }
}

例如,对于下图所示的二叉树:

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

它的后序遍历结果为: 4 5 2 6 7 3 1

5.层次遍历二叉树

层次遍历的顺序是:按照从上往下、从左往右的方式,逐层遍历每一个节点。以下是一个示例代码:

void levelOrderTraverse(TreeNode* root){
    if(root == NULL){
        return;
    }
    Queue q;
    initQueue(&q);
    enqueue(&q, root);
    while(!isEmpty(&q)){
        TreeNode* node = dequeue(&q);
        printf("%d ", node->data);
        if(node->left != NULL) enqueue(&q, node->left);
        if(node->right != NULL) enqueue(&q, node->right);
    }
}

其中,使用队列来存储每一层的节点队列,先将根节点入队,之后每次出队一个节点并输出,再将该节点的左右子节点入队。

例如,对于下图所示的二叉树:

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

它的层次遍历结果为: 1 2 3 4 5 6 7

6.非递归查找

使用非递归的方式,从根节点开始查找二叉树中是否存在某个节点。以下是一个示例代码:

TreeNode* find(TreeNode* root, int val){
    if(root == NULL) return NULL;
    Stack s;
    initStack(&s);
    push(&s, root);
    while(!isEmptyStack(&s)){
        TreeNode* node = top(&s); pop(&s);
        if(node->data == val) return node;
        if(node->right != NULL) push(&s, node->right);
        if(node->left != NULL) push(&s, node->left);
    }
    return NULL;
}

其中,使用栈来存储每一个节点,先将根节点入栈,之后每次取出一个节点并比较,如果相等则返回该节点,否则将其右子节点和左子节点入栈。

7.统计节点个数

统计二叉树中节点的个数,包括根节点和左右子树中的所有节点。以下是一个示例代码:

int count(TreeNode* root){
    if(root == NULL) return 0;
    return count(root->left) + count(root->right) + 1;
}

其中,使用递归的方式遍历每一个节点,并计数。

8.二叉树比较

比较两个二叉树是否相同,相同返回 true,否则返回 false。以下是一个示例代码:

bool isEqual(TreeNode* root1, TreeNode* root2){
    if(root1 == NULL && root2 == NULL) return true;
    if(root1 == NULL || root2 == NULL) return false;
    if(root1->data != root2->data) return false;
    return isEqual(root1->left, root2->left) && isEqual(root1->right, root2->right);
}

其中,使用递归的方式分别比较两个二叉树的根节点、左子树和右子树。

9.求二叉树深度

求二叉树的深度,即二叉树的最大深度。以下是一个示例代码:

int maxDepth(TreeNode* root){
    if(root == NULL) return 0;
    int left = maxDepth(root->left);
    int right = maxDepth(root->right);
    return left > right ? left + 1 : right + 1;
}

其中,使用递归的方式分别求左子树和右子树的深度,并加上根节点的深度 1,最后返回较大值。

示例说明

示例一

我们输入以下数据:

1
2
4
-1
-1
5
-1
-1
3
6
-1
-1
7
-1
-1

使用示例代码中的 createBinaryTree() 方法,得到以下的二叉树:

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

使用示例代码中的各种遍历、查找、比较、求深度等方法可以对该二叉树进行各种操作。

示例二

我们输入以下数据:

1
-1
2
-1
3
-1

使用示例代码中的 createBinaryTree() 方法,得到以下的二叉树:

  1
   \
    2
     \
      3

使用示例代码中的各种遍历、查找、比较、求深度等方法可以对该二叉树进行各种操作,例如:

  • 中序遍历结果: 1 2 3
  • 非递归查找 4,结果为 NULL
  • 统计节点个数为 3
  • 求深度为 3

总结

二叉树是一种常用的数据结构,常用的操作包括创建、遍历、查找、比较和求深度等。掌握这些基本操作后,可根据实际需求进行扩展。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C语言二叉树常见操作详解【前序,中序,后序,层次遍历及非递归查找,统计个数,比较,求深度】 - Python技术站

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

相关文章

  • 【linux】tree命令安装和使用

    以下是Linux下tree命令安装和使用的完整攻略,包括以下内容: 概述 tree命令的安装 tree命令的基本用法 tree命令的高级用法 示例说明 1. 概述 tree命令是一款在Linux系统中常用的目录树显示工具,可以以树形结构显示目录和文件的层次结构。本文将介绍如何在Linux系统中安装和使用tree命令。 2. tree命令的安装 tree命令通…

    other 2023年5月9日
    00
  • vue测试环境打包与生产环境打包文件数量不一致解决方案

    一、问题描述 在使用 Vue.js 进行开发时,一些同学可能遇到过这样的情况:在测试环境下打包出来的文件数量与在生产环境下打包出来的文件数量不一致,并且测试环境下打包出来的文件数量更多。 二、原因分析 造成这个问题的原因比较复杂,主要有以下几点: 1.测试环境下可能会有一些调试和性能分析的代码,比如 source map、开发环境的调试工具等等。 2.在测试…

    other 2023年6月27日
    00
  • 强大的健身软件——Keep

    强大的健身软件——Keep的完整攻略 Keep是一款非常受欢迎的健身软件,它提供了丰富的健身课程和社区功能,帮助用户实现健身目标。本文将为您提供Keep的完整攻略,包括基本概念、使用方法、以及两个示例说明。 基本概念 Keep是一款健身软件,提供了丰富的健身课程和社区功能。用户可以通过Keep选择适合自己的健身课程,跟随教练进行训练,还可以通过社区功能与其他…

    other 2023年5月6日
    00
  • 7款易上手c语言编程软件推荐

    7款易上手C语言编程软件推荐 C语言是一门广泛应用于系统编程、嵌入式系统和游戏开发的编程语言。想要学好C语言,选用适合自己的编程软件是非常重要的。本文将为大家推荐7款易上手的C语言编程软件。 1. Dev-C++ Dev-C++是一个免费的、开源的IDE集成开发环境,它支持C语言和C++,可以在Windows操作系统上运行。Dev-C++提供了基本的编辑器和…

    其他 2023年3月29日
    00
  • 一文搞懂JAVA 修饰符

    一文搞懂JAVA 修饰符 在Java中,修饰符(Modifier)是用来限制或者开放类、接口、方法和变量的访问权限;限制或者限制方法的继承或其他行为。Java中的修饰符分为以下几种: 访问控制修饰符:public,private,protected和默认(即不写)四种修饰符。 继承控制修饰符:final 和 abstract 两种修饰符。 静态修饰符:sta…

    other 2023年6月26日
    00
  • Python栈的实现方法示例【列表、单链表】

    下面我将详细讲解Python栈的实现方法,包括列表和单链表两种方法。 什么是栈? 在开始讲解栈的实现方法之前,我们需要先了解什么是栈。栈(Stack)是一种先进后出的数据结构,它只允许在一端进行插入和删除操作,这一端通常称为栈顶。栈被广泛应用于计算机中,例如函数调用、表达式求值、括号匹配等。 列表实现栈 在Python中,可以使用列表(list)来实现栈。列…

    other 2023年6月27日
    00
  • 如何在 Illustrator 中使用图层 ai图层使用教程

    如何在 Illustrator 中使用图层 在 Adobe Illustrator 中,图层是组织和管理设计元素的重要工具。以下是使用图层的详细攻略: 创建图层 打开 Adobe Illustrator,并打开您的设计文件。 在右侧的“图层”面板中,点击底部的“新建图层”按钮(图标为一个方形和一个加号)。 输入图层的名称,并按下回车键创建图层。 图层的可见性…

    other 2023年10月15日
    00
  • ios基础篇(二十七)——json解析

    以下是关于“iOS基础篇(二十七)——JSON解析”的完整攻略: 什么是JSON JSON(JavaScript Object Notation)是一种轻量级的数据交换格式易于阅读和编,也易于机器解析和生成。JSON数据格式是一种键值对的数据结构,可以表示数字、字符串布尔值、数组和对象等数据类型。 JSON解析 在iOS中,可以使用NSJSONSeriali…

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