110、【树与二叉树】leetcode ——450. 删除二叉搜索树中的节点:递归法+迭代法(C++版本)
2023-09-11 14:20:01 时间
题目描述
原题链接:450. 删除二叉搜索树中的节点
解题思路
- 在删除操作时,要可获取父节点。
- 对于结点值等于
key
的结点,删除可能会出现三种情况。
(1)左、右子树都为空,则直接返回NULL
;
(2)当一侧为空,一侧不为空,则返回不为空的孩子;
(3)当左、右两侧都不为空,则将一侧孩子插入另一侧下面,再返回新构建的孩子。
1、先序遍历递归法
采用递归的方式,未找到时,根据值的大小,向对应一侧遍历,让其指针指向对应一侧。找到时,对节点进行处理后,返回节结点。
/**
* Definition for a binary tree node.
* 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) {}
* };
*/
class Solution {
public:
TreeNode* deleteNode(TreeNode* root, int key) {
if(!root) return NULL;
if(root->val == key) {
if(!root->left && !root->right)
return NULL;
TreeNode* temp = root; // temp用于删除该结点
if(root->left && !root->right) { // 左不空,右空,返回左
root = root->left;
} else if(root->right && !root->left) { // 左空,右不空,返回右
root = root->right;
} else if(root->left && root->right) { // 左右都不空,将右插入到左的最右边
TreeNode* cur = root->left;
while(cur->right) cur = cur->right;
cur->right = root->right; // 插入左孩子的右下角
root = root->left; // 返回左孩子
}
delete temp; // 删除等于key的结点
return root;
}
// 左、右向下遍历时,已经包含了父节点指向的关系,只需对找到结点处理即可。
if(root->val > key) root->left = deleteNode(root->left, key);
else if(root->val < key) root->right = deleteNode(root->right, key);
return root;
}
};
2、迭代法
/**
* Definition for a binary tree node.
* 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) {}
* };
*/
class Solution {
public:
TreeNode* transformTree(TreeNode* cur, int key) {
TreeNode* node = cur;
if(!cur->left && !cur->right) { // 左右无孩子,直接返回NULL
return NULL;
} else if (!cur->left) { // 左空,右不空,node指向右
node = cur->right;
} else if (!cur->right) { // 右空,左不空,node指向左
node = cur->left;
} else if (cur->left && cur->right) { // 左右都不空,让左子树的右下角结点指向,右子树
TreeNode* p = cur->left;
while(p->right) p = p->right;
p->right = cur->right;
node = cur->left; // 让node指向左子树
}
return node;
}
TreeNode* deleteNode(TreeNode* root, int key) {
if(!root) return NULL;
// 寻找删除点
TreeNode* cur = root;
TreeNode* pre = NULL;
while(cur) {
if(cur->val == key) break;
pre = cur;
if(cur->val > key) cur = cur->left;
else cur = cur->right;
}
// 没找到,则直接返回root
if(!cur) return root;
// 若删除的为根节点,改变root的值
if(!pre) root = transformTree(cur, key);
// 当删除的为某结点的左孩子
else if(pre->left && pre->left->val == key)
pre->left = transformTree(cur, key);
// 当删除的为某结点的右孩子
else if(pre->right && pre->right->val == key)
pre->right = transformTree(cur, key);
// 删除该结点
delete cur;
return root;
}
};
参考文章:450.删除二叉搜索树中的节点
相关文章
- GSL+DevC++使用
- C++第7周任务1-求两数正差值
- c++中.dll与.lib文件的生成与使用的详解
- 《C++入门经典(第6版)》——2.4 函数
- 《C++面向对象高效编程(第2版)》——3.12 参数传递模式——客户的角度
- 基于QT(C++)实现(图形界面)旅行模拟查询系统【100010631】
- 基于C++实现(控制台)人事管理系统【100010009】
- C++ 预编译头文件
- c++ 默认构造函数 不同编译器debug和release的区别
- C++ ------ 虚函数覆盖、重载
- 198、【动态规划】leetcode ——983. 最低票价:记忆化搜索(C++版本)
- 158、【动态规划】leetcode ——518. 零钱兑换 II:二维数组+一维滚动数组(C++版本)
- 127、【贪心算法】leetcode ——455. 分发饼干:DFS+双指针法(C++版本)
- 116、【回溯算法】leetcode ——17. 电话号码的字母组合:回溯法:哈希映射+字符串数组映射(C++版本)
- 111、【树与二叉树】leetcode ——669. 修剪二叉搜索树:递归法(C++版本)
- 108、【树与二叉树】leetcode ——235. 二叉搜索树的最近公共祖先:普通树解法+BST性质解法(C++版本)
- 98、【树与二叉树】leetcode ——112. 路径总和:5行精简代码回溯法[带剪枝]+迭代法(C++版本)
- 79、【字符串】leetcode ——28. 找出字符串中第一个匹配项的下标(C++版本)
- 74、【数组】leetcode——18. 四数之和(C++版本)
- 72、【哈希表】leetcode——454. 四数相加 II(C++版本)
- 64、【链表】leetcode——203. 移除链表元素(C++版本)
- C++实操 - 访问控制