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日

相关文章

  • 详解Java数据结构之平衡二叉树

    详解Java数据结构之平衡二叉树 什么是平衡二叉树? 平衡二叉树(Balanced Binary Tree)是一种特殊的二叉搜索树,它的左子树和右子树的高度差不超过1,这样可以保证在最坏情况下,查找、插入、删除等操作的时间复杂度都是O(log n)。 平衡二叉树的基本性质 左子树和右子树的高度差不超过1。 平衡二叉树的左右子树也是平衡二叉树。 如何实现? 平…

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

    数据结构之堆详解 什么是堆? 堆(Heap)是一种特殊的树形数据结构。堆具有以下两个特点: 堆是一颗完全二叉树; 堆中每个节点的值都必须大于等于或小于等于其左右子节点的值,分别称作大根堆和小根堆。 上述的大根堆和小根堆其实是两种不同的堆的实现方式。对于大根堆,每个节点的值都比其左右子节点的值要大;小根堆则相反,每个节点的值都比其左右子节点的值要小。 堆的基本…

    数据结构 2023年5月17日
    00
  • java实现队列queue数据结构详解

    Java实现队列(Queue)数据结构详解 什么是队列(Queue) 队列(Queue),是一种先进先出(First In First Out, FIFO)的数据结构,即最先进入队列的元素也会最先出队列。 队列具备两个基本操作:入队(enqueue)和出队(dequeue)。入队操作将元素加入到队列的尾部,出队操作将元素从队列头部取出并删除。 Java中的Q…

    数据结构 2023年5月17日
    00
  • C语言数据结构树的双亲表示法实例详解

    C语言数据结构树的双亲表示法实例详解 什么是双亲表示法 在树上,每个节点都有且仅有一个父节点(根节点除外)。对于一个树结构,我们可以使用许多方法来表示这个树,其中最常见的一种方法是双亲表示法。该表示法使用一个一维数组来存储树的节点,数组的下标即为该节点的编号,数组的值则表示该节点的父节点编号。 当一个节点没有父节点时,该节点即为根节点。 双亲表示法的优缺点 …

    数据结构 2023年5月17日
    00
  • LCA——ST表+欧拉序

    了解到一个quan新的东西: 用ST表(欧拉序)实现LCA(树上最近公共祖先) 欧拉序 前序遍历得到的序列,叫dfs序但数字可以重复出现,一进一出,叫欧拉序会发现根结点总在中间而根结点是该段序列深度最小的点因此两个点的LCA,就是在该序列上两个点第一次出现的区间内深度最小的那个点 即转化为区间RMQ问题,可以用ST表当然你可以再写一棵线段树(如果有修改操作)…

    算法与数据结构 2023年5月4日
    00
  • 数据结构之哈夫曼树与哈夫曼编码

    一、背景 编码是信息处理的基础(重新表示信息)。 普通的编码是等长编码,例如7位的ASCIL编码,对出现频率不同的字符都使用相同的编码长度。但其在传输和存储等情况下编码效率不高。 可使用不等长编码,来压缩编码:高频字符编码长度更短,低频字符编码长度更长。   [例] 将百分制的考试成绩转换成五分制的成绩 按顺序分别编码。 按频率分别编码(高频短编码,类似于香…

    算法与数据结构 2023年4月17日
    00
  • C语言数据结构之堆排序的优化算法

    C语言数据结构之堆排序的优化算法攻略 堆排序简介 堆排序(HeapSort)是一种树形选择排序,在排序过程中始终保持一个最大堆,每次将堆顶元素与最后一个元素交换位置,并进行一次最大堆调整操作,直到整个序列有序为止。 堆排序的时间复杂度为O(nlogn),具有不需额外存储空间的特点,因此广泛应用于内存受限的场景。 堆排序的优化算法 1. 建堆操作的优化 将序列…

    数据结构 2023年5月17日
    00
  • C语言顺序表的基本结构与实现思路详解

    C语言顺序表的基本结构与实现思路详解 什么是顺序表 顺序表,顾名思义,就是使用连续的存储空间来存储数据元素的线性表。在顺序表中,每一个数据元素都占用一个连续的存储单元,这些存储单元在物理上连续存放,因此,顺序表实际上就是由一个存储数据元素的数组和记录该数组大小的变量组成的。 顺序表的基本结构 顺序表的定义 “`c #define MAXSIZE 100 /…

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