C++二叉树结构的建立与基本操作

C++二叉树是一种非常常见的数据结构,同时也是算法中经常使用的一种数据结构。本文将详细讲解C++二叉树的建立和基本操作,包括二叉树的定义、创建、遍历和删除等。

1. 二叉树的定义

二叉树是一种树形结构,每个节点最多只有两个子节点:左子节点和右子节点。树的深度取决于有多少个节点,根节点是最顶端的节点,不再有父节点。节点之间存在一些有天然排序关系且有先后性的关系,因此二叉树通常用于查找、排序等算法中。

二叉树的节点可以用一个结构体来定义,结构体中包含了一个指向左子节点和右子节点的指针,以及一个数据域,如下所示:

struct TreeNode{
    int data;                // 数据域
    TreeNode* left;          // 左子节点指针
    TreeNode* right;         // 右子节点指针
    TreeNode(int val)        // 构造函数
    : data(val), left(nullptr), right(nullptr){}
};

2. 二叉树的创建

二叉树的创建可以采用递归的方式,先创建根节点,再创建左右子树。具体实现如下:

TreeNode* CreateBinaryTree(){
    int val;
    cout << "输入节点的值(-1代表空节点):";
    cin >> val;
    if(val == -1){
        return nullptr;     // 空节点
    }
    TreeNode* node = new TreeNode(val);     // 创建新节点
    node->left = CreateBinaryTree();        // 创建左子树
    node->right = CreateBinaryTree();       // 创建右子树
    return node;
}

3. 二叉树的遍历

二叉树的遍历主要有三种方式:前序遍历、中序遍历和后序遍历。

前序遍历

前序遍历的思路是先遍历节点本身,再遍历左子树,最后遍历右子树。具体实现如下:

void preorderTraversal(TreeNode* root){
    if(root == nullptr){
        return;         // 空树,直接返回
    }
    cout << root->data << " ";         // 遍历根节点
    preorderTraversal(root->left);     // 遍历左子树
    preorderTraversal(root->right);    // 遍历右子树
}

中序遍历

中序遍历的思路是先遍历左子树,再遍历节点本身,最后遍历右子树。具体实现如下:

void inorderTraversal(TreeNode* root){
    if(root == nullptr){
        return;         // 空树,直接返回
    }
    inorderTraversal(root->left);      // 遍历左子树
    cout << root->data << " ";         // 遍历根节点
    inorderTraversal(root->right);     // 遍历右子树
}

后序遍历

后序遍历的思路是先遍历左子树,再遍历右子树,最后遍历节点本身。具体实现如下:

void postorderTraversal(TreeNode* root){
    if(root == nullptr){
        return;         // 空树,直接返回
    }
    postorderTraversal(root->left);    // 遍历左子树
    postorderTraversal(root->right);   // 遍历右子树
    cout << root->data << " ";         // 遍历根节点
}

4. 二叉树的删除

二叉树的删除主要有三种情况:

  • 被删除节点没有子节点,直接删除
  • 被删除节点只有一个子节点,将其子节点代替该节点
  • 被删除节点有两个子节点,将右子树中的最小值替换到该节点

具体实现代码如下:

TreeNode* deleteNode(TreeNode* root, int target){
    if(root == nullptr){
        return nullptr;     // 空树,直接返回
    }
    if(root->data == target){   // 找到了要删除的节点
        if(root->left == nullptr && root->right == nullptr){   // 情况一:被删除节点没有子节点
            delete root;
            return nullptr;
        }
        if(root->left == nullptr){    // 情况二:被删除节点只有一个右子节点
            TreeNode* tmp = root->right;
            delete root;
            return tmp;
        }
        if(root->right == nullptr){   // 情况二:被删除节点只有一个左子节点
            TreeNode* tmp = root->left;
            delete root;
            return tmp;
        }
        // 情况三:被删除节点有两个子节点
        TreeNode* minNode = root->right;   // 找到右子树中最小的节点
        while(minNode->left != nullptr){
            minNode = minNode->left;
        }
        root->data = minNode->data;        // 将最小值替换到被删除节点
        root->right = deleteNode(root->right, minNode->data);    // 删除右子树中的最小值
    }else if(root->data > target){
        root->left = deleteNode(root->left, target);    // 左子树中删除
    }else{
        root->right = deleteNode(root->right, target);  // 右子树中删除
    }
    return root;
}

5. 示例说明

示例1

输入数据:1 2 4 -1 -1 -1 3 -1 5 -1 -1

其中-1代表空节点,这个输入数据代表的二叉树如下所示:

graph LR
1((1)) --> 2((2))
1 --> 3((3))
2 --> 4((4))
3 --> 5((5))

输出数据:

前序遍历结果为:1 2 4 3 5

中序遍历结果为:4 2 1 3 5

后序遍历结果为:4 2 5 3 1

示例2

输入数据:5 3 2 -1 -1 4 -1 -1 7 6 -1 -1 8 -1 -1

其中-1代表空节点,这个输入数据代表的二叉树如下所示:

graph LR
5((5)) --> 3((3))
5 --> 7((7))
3 --> 2((2))
3 --> 4((4))
7 --> 6((6))
7 --> 8((8))

输出数据:

前序遍历结果为:5 3 2 4 7 6 8

中序遍历结果为:2 3 4 5 6 7 8

后序遍历结果为:2 4 3 6 8 7 5

以上就是C++二叉树的建立与基本操作的完整攻略。如果还有疑问,请留言询问。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C++二叉树结构的建立与基本操作 - Python技术站

(0)
上一篇 2023年5月17日
下一篇 2023年5月17日

相关文章

  • 【ACM数论】和式变换技术,也许是最好的讲解之一

    在做数论题时,往往需要进行和式变换,然后变换成我们可以处理的和式,再针对和式做筛法、整除分块等操作。 本文将介绍一些常见的和式变换技术。 以下出现的概念大部分为个人总结,未必是学术界/竞赛界的统一说法,有不严谨的地方请谅解。 ? 作者:Eriktse? 简介:19岁,211计算机在读,现役ACM银牌选手?力争以通俗易懂的方式讲解算法!❤️欢迎关注我,一起交流…

    算法与数据结构 2023年4月17日
    00
  • 蒙特卡罗方法:当丢失确定性时的处理办法

    一、简介   蒙特卡罗(Monte Carlo),也可翻译为蒙特卡洛,只是不同的音译选词,比较常用的是蒙特卡罗。是摩洛哥的一片城区,以拥有豪华赌场闻名,蒙特卡罗方法是基于概率的。基本思想:如果你想预测一件事情的结果,你只要把随机生成的各种输入值,把这件事模拟很多遍,根据模拟出的结果就可以看到事情的结果大致是什么情况。蒙特卡罗算法是基于蒙特卡罗方法的算法。 二…

    算法与数据结构 2023年4月17日
    00
  • 简单讲解哈希表

    哈希表(Hash Table),也被称为散列表,是一种高效的数据结构,它可以在O(1)的时间复杂度下完成插入、删除、查找等基本操作。哈希表是通过将关键字映射到一个固定大小的表中来实现的,这个映射函数被称为哈希函数。 什么是哈希函数 哈希函数是将任意长度的输入值(也称为“键”或“关键字”)映射为固定大小的输出值(也称为“哈希值”或“散列”)。哈希函数必须将不同…

    数据结构 2023年5月17日
    00
  • 数据结构之AVL树详解

    数据结构之AVL树详解 什么是AVL树? AVL树是一种自平衡的二叉搜索树,它的名称来自它的发明者Adelson-Velsky和Landis。在AVL树中,每个节点的左右子树的高度差(平衡因子)最多为1,否则需要通过旋转操作来重新平衡树。AVL树基于二叉搜索树,所以它包含了二叉搜索树的所有特性,同时也保证了树的高度始终处于对数级别,因此它的查找、插入、删除都…

    数据结构 2023年5月16日
    00
  • 常用内核架构

      本文分享自天翼云开发者社区《常用内核架构》,作者:JackW   宏内核 应用程序调用内存分配的 API(应用程序接口)函数。 处理器切换到特权模式,开始运行内核代码。 内核里的内存管理代码按照特定的算法,分配一块内存。 把分配的内存块的首地址,返回给内存分配的 API 函数。 内存分配的 API 函数返回,处理器开始运行用户模式下的应用程序,应用程序就…

    算法与数据结构 2023年4月22日
    00
  • React前端解链表数据结构示例详解

    我将为您详细讲解“React前端解链表数据结构示例详解”的完整攻略。 React前端解链表数据结构示例详解 一、前置知识 在学习本篇文章之前,您需要掌握以下前置知识: 基本的 JavaScript 语法 React 中的组件概念和生命周期 链表数据结构的基本概念和操作方法 如果您对以上知识点还不是很熟悉,可以先自学相关知识再来阅读本文。 二、链表数据结构简介…

    数据结构 2023年5月17日
    00
  • C++数据结构之链表详解

    C++数据结构之链表详解 链表是一种重要的数据结构,它可以动态的分配内存空间,实现灵活的元素插入,删除等操作。本文将详细讲解链表的定义、实现、常见操作以及链表的应用。 定义与特点 链表是一种线性表数据结构,由一系列节点组成,每个节点包含数据和指向下一个节点的指针。链表分为单向链表和双向链表,其中单向链表的每个节点只包含一个指针,指向下一个节点,而双向链表的每…

    数据结构 2023年5月17日
    00
  • 带你了解Java数据结构和算法之2-3-4树

    带你了解Java数据结构和算法之2-3-4树 1. 什么是2-3-4树 2-3-4树是一种自平衡二叉查找树,也叫B树的一种,它可以保持树的平衡,使得每个节点的左右子树高度差最多为1。在2-3-4树中,每个节点可以包含2个、3个或4个子节点,这也是其名称的来源。2-3-4树是B树的特殊形式,通常用于内存储存结构。 2. 2-3-4树的特点 2-3-4树的特点如…

    数据结构 2023年5月17日
    00
合作推广
合作推广
分享本页
返回顶部