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

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日

相关文章

  • Xshell怎么开启布局管理?Xshell开启布局管理教程

    Xshell怎么开启布局管理 Xshell是一款功能强大的终端模拟器,可以通过开启布局管理来实现多个终端窗口的同时显示和管理。下面是详细的攻略: 步骤一:打开Xshell 首先,双击打开Xshell应用程序。 步骤二:创建新会话 在Xshell的菜单栏中,点击\”文件\”,然后选择\”新建\”,再选择\”会话\”。这将打开一个新的会话窗口。 步骤三:开启布局…

    other 2023年9月5日
    00
  • Win7安装和配置Apache2.4服务器的详细方法

    以下是详细讲解“Win7安装和配置Apache2.4服务器的详细方法”的攻略: 准备工作 在开始安装和配置Apache2.4服务器之前,需要先进行一些准备工作。 下载Apache2.4的安装程序(apachehaus)。 下载VC运行库(Visual C++ Redistributable for Visual Studio 2015)。 关闭防火墙和杀毒软…

    other 2023年6月27日
    00
  • C++浅析构造函数的特性

    C++浅析构造函数的特性 什么是构造函数 在C++中,构造函数是一种特殊的成员函数,用于初始化对象的成员变量。当定义一个对象时,系统会自动调用构造函数进行变量初始化,构造函数名称和类名称要相同,并且没有返回值。 构造函数的特性 构造函数的重载 在C++中,构造函数可以重载。即可以有多个构造函数,每个构造函数可以有不同的参数列表和实现方式。使用重载的构造函数可…

    other 2023年6月26日
    00
  • 联想笔记本怎么一键恢复 联想笔记本恢复出厂设置教程

    联想笔记本一键恢复教程 为了让联想笔记本恢复到出厂设置,我们可以采用一键恢复的方式。此操作会删除所有的数据,所以在执行此操作之前,用户需要备份好自己的所有重要数据。 步骤1:启动联想笔记本并进入恢复界面 打开联想笔记本,保证电脑处于关机状态。 开机后,在联想图标出现之前按下F12键,可以进入BIOS启动菜单。 在启动菜单中,选择“启动计算机修复程序”并回车。…

    other 2023年6月20日
    00
  • 电脑截图快捷键是什么

    电脑截图快捷键是指在电脑上快速进行截图操作的快捷键。常用的电脑截图快捷键有以下两种: Windows系统下的截图快捷键: 按下“Win+Print Screen”键,可把整个屏幕截图保存到计算机本地的“图片”文件夹下; 按下“Alt+Print Screen”键,可将当前活动窗口截图复制到剪贴板,可在图片编辑软件中使用“Ctrl+V”进行粘贴处理。 MacO…

    其他 2023年4月16日
    00
  • vim进入粘贴模式

    vim进入粘贴模式 什么是vim vim是Unix和类Unix系统上的一种文本编辑器,也是Linux发行版中预装的编辑器之一。它具有强大的编辑功能和良好的可定制性,可以用于编写各种类型的文本文件,例如代码、配置文件、Markdown文档等。 什么是粘贴模式 在使用vim编辑器过程中,有时候我们需要从其他应用程序复制文本粘贴到vim编辑器中。但是,由于vim编…

    其他 2023年3月29日
    00
  • 电脑开机提示:您已使用临时配置文件登陆的解决办法

    电脑开机提示:您已使用临时配置文件登陆的解决办法 当我们开机时,有时会遇到一个叫做“临时配置文件”的问题,这时候我们需要通过以下步骤来解决。 问题原因 在 Windows 操作系统中,每个用户登录后都会生成一个用户配置文件,此文件中包含了当前用户的各种系统设置信息,例如桌面背景、文件路径、软件设置等等。但有时候,由于一些原因(例如系统崩溃、硬件故障等),Wi…

    other 2023年6月25日
    00
  • Netty分布式server启动流程Nio创建源码分析

    Netty是一个基于Java NIO库开发的高性能、异步非阻塞的网络编程框架,被广泛应用于分布式系统中。本文将详细讲解Netty分布式server启动流程Nio创建源码分析,包括以下内容: Netty启动流程分析 Nio创建流程分析 示例说明 1. Netty启动流程分析 Netty启动流程可以分为以下几个步骤: 创建ServerBootstrap实例 设置…

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