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`函数来释放树占用的内存。

相关推荐
结衣结衣.11 分钟前
python中的函数介绍
java·c语言·开发语言·前端·笔记·python·学习
茫茫人海一粒沙14 分钟前
Python 代码编写规范
开发语言·python
原野心存14 分钟前
java基础进阶知识点汇总(1)
java·开发语言
程序猿阿伟16 分钟前
《C++高效图形用户界面(GUI)开发:探索与实践》
开发语言·c++
暗恋 懒羊羊25 分钟前
Linux 生产者消费者模型
linux·开发语言·ubuntu
阿客不是客30 分钟前
深入计算机语言之C++:C到C++的过度
c++
LN-ZMOI37 分钟前
c++学习笔记1
c++·笔记·学习
no_play_no_games41 分钟前
「3.3」虫洞 Wormholes
数据结构·c++·算法·图论
￴ㅤ￴￴ㅤ9527超级帅41 分钟前
LeetCode hot100---数组及矩阵专题(C++语言)
c++·leetcode·矩阵
五味香41 分钟前
C++学习,信号处理
android·c语言·开发语言·c++·学习·算法·信号处理