二叉排序树的插入、删除实现
二叉排序树的结构体声明:
struct TreeNode {
int val;
TreeNode *left; // 左节点
TreeNode *right; // 右节点
TreeNode() : val(0), left(nullptr), right(nullptr) {}
TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
};
二叉排序树的插入操作
二叉排序树的插入操作,本质上和查找类似,通过递归很容易实现:
void insert(TreeNode*& root, int v){
// 向 根节点为 root 的树插入 数据 v
if (root == nullptr) {
root = new TreeNode(v);
return ;
}
if (root->val < v) {
insert(root->right, v);
}else if (root->val > v) {
insert(root->left, v);
} else {
return ;
}
return ;
}
二叉排序树的删除操作
二叉排序树的删除操作更为复杂一些:
- 如果当前节点是叶子节点,可以直接删除。
- 如果当前节点只有左子树或者只有右子树,直接使用子节点替换当前节点即可。
- 如果当前节点既有左子树又有右子树,应当让右子树的最左下方节点替换它。
代码实现:
void deleteV(TreeNode*& root,int v){
// 向 根节点为 root 的树插入 数据 v
if (root == nullptr) {
cout << "删除节点失败!" << endl;
return;
}
if (root->val < v) {
deleteV(root->right, v);
}else if (root->val > v) {
deleteV(root->left, v);
}else {
if (root->left == nullptr && root->right == nullptr)
root = nullptr, delete root; // 如果左右子树都为空,直接删除该节点
else if (root->left && root->right) { // 如果左右子树都存在
// 查找中序排序的下一个节点
TreeNode* nxtTreeNode;
nxtTreeNode = root->right;
while (nxtTreeNode->left)
nxtTreeNode = nxtTreeNode->left;
// 交换两个节点的值
swap(nxtTreeNode->val, root->val);
deleteV(root->right, v);
} else if (root->left) { // 左不为空, 右为空
TreeNode* tmp = root;
root = root->left;
delete tmp;
} else { // 左为空,右不为空
TreeNode* tmp = root;
root = root->right;
delete tmp;
}
}
return ;
}
代码测试
void preOrder(TreeNode* root){
if (root == nullptr) return;
cout << root->val << ", ";
preOrder(root->left);
preOrder(root->right);
}
void inOrder(TreeNode* root){
if (root == nullptr) return;
inOrder(root->left);
cout << root->val << ", ";
inOrder(root->right);
}
int main(){
vector<int> nums{53, 78, 65, 94, 81, 88, 17, 9, 45, 23};
TreeNode* root = nullptr;
for (int num : nums) {
insert(root, num);
}
cout << "preOrder: ";
preOrder(root);
cout << endl;
cout << "inOrder: ";
inOrder(root);
cout << endl;
deleteV(root, 78);
cout << "preOrder: ";
preOrder(root);
cout << endl;
cout << "inOrder: ";
inOrder(root);
cout << endl;
return 0;
}
测试结果
preOrder: 53, 17, 9, 45, 23, 78, 65, 94, 81, 88
inOrder: 9, 17, 23, 45, 53, 65, 78, 81, 88, 94
preOrder: 53, 17, 9, 45, 23, 81, 65, 94, 88
inOrder: 9, 17, 23, 45, 53, 65, 81, 88, 94
完整代码
#include<bits/stdc++.h>
using namespace std;
struct TreeNode {
int val;
TreeNode *left; // 左节点
TreeNode *right; // 右节点
TreeNode() : val(0), left(nullptr), right(nullptr) {}
TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
};
void insert(TreeNode*& root, int v){
// 向 根节点为 root 的树插入 数据 v
if (root == nullptr) {
root = new TreeNode(v);
return ;
}
if (root->val < v) {
insert(root->right, v);
}else if (root->val > v) {
insert(root->left, v);
} else {
return ;
}
return ;
}
void deleteV(TreeNode*& root,int v){
// 向 根节点为 root 的树插入 数据 v
if (root == nullptr) {
cout << "删除节点失败!" << endl;
return;
}
if (root->val < v) {
deleteV(root->right, v);
}else if (root->val > v) {
deleteV(root->left, v);
}else {
if (root->left == nullptr && root->right == nullptr)
root = nullptr, delete root; // 如果左右子树都为空,直接删除该节点
else if (root->left && root->right) { // 如果左右子树都存在
// 查找中序排序的下一个节点
TreeNode* nxtTreeNode;
nxtTreeNode = root->right;
while (nxtTreeNode->left)
nxtTreeNode = nxtTreeNode->left;
// 交换两个节点的值
swap(nxtTreeNode->val, root->val);
deleteV(root->right, v);
} else if (root->left) { // 左不为空, 右为空
TreeNode* tmp = root;
root = root->left;
delete tmp;
} else { // 左为空,右不为空
TreeNode* tmp = root;
root = root->right;
delete tmp;
}
}
return ;
}
void preOrder(TreeNode* root){
if (root == nullptr) return;
cout << root->val << ", ";
preOrder(root->left);
preOrder(root->right);
}
void inOrder(TreeNode* root){
if (root == nullptr) return;
inOrder(root->left);
cout << root->val << ", ";
inOrder(root->right);
}
int main(){
vector<int> nums{53, 78, 65, 94, 81, 88, 17, 9, 45, 23};
TreeNode* root = nullptr;
for (int num : nums) {
insert(root, num);
}
cout << "preOrder: ";
preOrder(root);
cout << endl;
cout << "inOrder: ";
inOrder(root);
cout << endl;
deleteV(root, 78);
cout << "preOrder: ";
preOrder(root);
cout << endl;
cout << "inOrder: ";
inOrder(root);
cout << endl;
return 0;
}
从以上测试结果来看,代码应当没有很大的问题,可放心食用~
创作不易,欢迎点赞,感谢~~