在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);
}
}
}
遍历二叉树主要有三种方式:前序遍历、中序遍历和后序遍历。
- 前序遍历(根-左-右),代码如下:
cpp
void preorderTraversal(TreeNode* root) {
if (root == nullptr) return;
cout << root->val << " ";
preorderTraversal(root->left);preorderTraversal(root->right);
}
- 中序遍历(左-根-右),代码如下:
cpp
void inorderTraversal(TreeNode* root) {
if (root == nullptr) return;
inorderTraversal(root->left);
cout << root->val << " ";
inorderTraversal(root->right);
}
- 序遍历(左-右-根),代码如下:
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`函数来释放树占用的内存。