C++的数据结构(六):树的基本操作和遍历

在C++中,二叉树是树的一种特殊形式,其中每个节点最多有两个子节点,通常称为左子节点和右子节点。我们可以通过结构或类来实现二叉树及其相关操作。

以下是一个简单的二叉树实现,包括创建、查找、插入、删除以及三种基本的遍历方式:前序遍历、中序遍历和后序遍历。

首先,我们需要定义一个二叉树节点:

cpp 复制代码
struct TreeNode {
    int val;
    TreeNode *left;
    TreeNode *right;
    TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
};

我们可以通过递归或者循环的方式创建二叉树,这里以递归为例:

cpp 复制代码
TreeNode* createTree() {
    // 假设我们使用某种方式读取或输入节点值,这里简化处理
    int val;
    cout << "Enter value (-1 for NULL): ";
    cin >> val;
    if (val == -1) return nullptr;
    
    TreeNode* root = new TreeNode(val);
    cout << "Enter left child of " << val << ": ";
    root->left = createTree();
    cout << "Enter right child of " << val << ": ";
    root->right = createTree();
    
    return root;
}

查找节点一般使用递归实现:

cpp 复制代码
TreeNode* search(TreeNode* root, int value) {
    if (root == nullptr || root->val == value) {
        return root;
    }
    TreeNode* found = search(root->left, value);
    if (found != nullptr) return found;
    return search(root->right, value);
}

插入节点的逻辑取决于二叉树的特定类型(例如,二叉搜索树)。在二叉搜索树中,节点根据值的大小插入到正确的位置。这里假设我们插入一个新节点到任意位置(不考虑搜索树的性质),代码如下:

cpp 复制代码
void insert(TreeNode*& root, int value) {
    if (root == nullptr) {
        root = new TreeNode(value);
        return;
    }
    if (value < root->val) {
        insert(root->left, value);
    } else {
        insert(root->right, value);
    }
}

删除节点的操作相对复杂,因为它需要考虑节点是否有子节点以及如何重新连接子树。以下是一个简化的删除操作示例,仅处理无子节点或只有一个子节点的情况,代码如下:

cpp 复制代码
void deleteNode(TreeNode*& root, int value) {
    if (root == nullptr) return;

    if (value < root->val) {
        deleteNode(root->left, value);
    } else if (value > root->val) {
        deleteNode(root->right, value);
    } else {
        // 节点找到,开始删除
        if (root->left == nullptr) {
            TreeNode* temp = root;
            root = root->right;
            delete temp;
        } else if (root->right == nullptr) {
            TreeNode* temp = root;
            root = root->left;
            delete temp;
        } else {
            // 找到右子树中的最小节点(或左子树中的最大节点)
            TreeNode* temp = root->right;
            while (temp->left != nullptr) {
                temp = temp->left;
            }
            // 将找到的节点值复制到当前节点
            root->val = temp->val;
            // 删除右子树中的最小节点
            deleteNode(root->right, temp->val);
        }
    }
}

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

  1. 前序遍历(根-左-右),代码如下:
cpp 复制代码
void preorderTraversal(TreeNode* root) {
    if (root == nullptr) return;
    cout << root->val << " ";
    preorderTraversal(root->left);preorderTraversal(root->right);
}
  1. 中序遍历(左-根-右),代码如下:
cpp 复制代码
void inorderTraversal(TreeNode* root) {
    if (root == nullptr) return;
    inorderTraversal(root->left);
    cout << root->val << " ";
    inorderTraversal(root->right);
}
  1. 序遍历(左-右-根),代码如下:
cpp 复制代码
void postorderTraversal(TreeNode* root) {
    if (root == nullptr) return;
    postorderTraversal(root->left);
    postorderTraversal(root->right);
    cout << root->val << " ";
}

以下是一个完整的示例,我们实现了一个简单的二叉搜索树(BST),查找二叉查找树中最大的值并提供了相应的功能函数。,代码如下:

cpp 复制代码
#include <iostream>
#include <cstdlib>
#include <ctime>

using namespace std;

// 二叉树节点定义
struct TreeNode {
    int val;
    TreeNode* left;
    TreeNode* right;
    TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};

// 插入节点
void insertNode(TreeNode*& root, int val) {
    if (root == NULL) {
        root = new TreeNode(val);
        return;
    }

    if (val < root->val) {
        insertNode(root->left, val);
    } else if (val > root->val) {
        insertNode(root->right, val);
    }
}

// 查找二叉查找树中的最大值
int findMaxValue(TreeNode* root) {
    if (root == NULL) {
        cout<<"Empty tree";
        return 0;
    }

    TreeNode* current = root;
    while (current->right != NULL) {
        current = current->right;
    }
    return current->val;
}

// 遍历整棵树并删除所有节点
void deleteTree(TreeNode*& root) {
    if (root == NULL) {
        return;
    }

    deleteTree(root->left);
    deleteTree(root->right);
    delete root;
    root = NULL;
}

// 生成随机数并插入到二叉查找树中
void insertRandomNodes(TreeNode*& root, int numNodes) {
    srand(time(0)); // 初始化随机数种子
    for (int i = 0; i < numNodes; ++i) {
        int randomVal = rand() % 100; // 生成0到99之间的随机数
        insertNode(root, randomVal);
    }
}

int main() {
    TreeNode* root = NULL;

    // 插入10个随机节点
    insertRandomNodes(root, 10);

    // 查找并输出二叉查找树中的最大值
    int maxValue = findMaxValue(root);
    cout << "Max value in the tree: " << maxValue << endl;
    
    // 释放树占用的内存
    deleteTree(root);

    return 0;
}

在上面的代码中,我们首先定义了一个`TreeNode`结构体来表示二叉树的节点。`insertNode`函数用于插入新节点到二叉查找树中。`findMaxValue`函数通过不断向右子节点遍历来查找并返回二叉查找树中的最大值。`deleteTree`函数通过递归的方式遍历整棵树并删除所有节点。`insertRandomNodes`函数用于生成随机数并插入到二叉查找树中。

在`main`函数中,我们创建了一个空的二叉树(`root`指针为`NULL`),然后调用`insertRandomNodes`函数插入10个随机节点。接下来,我们调用`findMaxValue`函数来查找并输出二叉查找树中的最大值。最后,我们调用`deleteTree`函数来释放树占用的内存。

相关推荐
筑基.几秒前
basic_ios及其衍生库(附 GCC libstdc++源代码)
开发语言·c++
蹉跎x6 分钟前
力扣1358. 包含所有三种字符的子字符串数目
数据结构·算法·leetcode·职场和发展
yuyanjingtao13 分钟前
CCF-GESP 等级考试 2023年12月认证C++三级真题解析
c++·青少年编程·gesp·csp-j/s·编程等级考试
雨颜纸伞(hzs)15 分钟前
C语言介绍
c语言·开发语言·软件工程
J总裁的小芒果17 分钟前
THREE.js 入门(六) 纹理、uv坐标
开发语言·javascript·uv
坊钰1 小时前
【Java 数据结构】移除链表元素
java·开发语言·数据结构·学习·链表
chenziang11 小时前
leetcode hot100 LRU缓存
java·开发语言
时雨h1 小时前
RuoYi-ue前端分离版部署流程
java·开发语言·前端
云计算DevOps-韩老师1 小时前
【网络云计算】2024第52周-每日【2024/12/25】小测-理论&实操-自己构造场景,写5个系统管理的脚本-解析
开发语言·网络·云计算·bash·perl
暮色尽染1 小时前
Python 正则表达式
开发语言·python