提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
提示:以下是本篇文章正文内容,下面案例可供参考
一、235二叉搜索树的最近公共祖先
class Solution {
public:
//p小 q大
TreeNode* traversal(TreeNode* node, TreeNode* p, TreeNode* q) {
if (node == nullptr) return node;
if (node->val > p->val && node->val > q->val) {
return traversal(node->left, p, q);
}
else if (node->val < p->val && node->val < q->val ) {
return traversal(node->right, p, q);
}
return node;
}
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
return traversal(root, p, q);
}
};
二、701二叉搜索树中的插入操作
笨办法做的,感觉这题让我写的无比复杂
class Solution {
public:
TreeNode* insertPos = nullptr;
void traversal(TreeNode* cur, int val) {
if (cur == nullptr) return;
traversal(cur->left, val);
if (insertPos == nullptr && cur->val >= val) {
insertPos = cur;
return;
}
traversal(cur->right, val);
}
TreeNode* insertIntoBST(TreeNode* root, int val) {
TreeNode* node = new TreeNode(val);
if (root == nullptr) return node;
traversal(root, val);
if (insertPos == nullptr) {
node->left = root;
return node;
}
TreeNode* temp = nullptr;
if (val < insertPos->val) {
temp = insertPos->left;
insertPos->left = node;
}
else if (val > insertPos->val) {
temp = insertPos->right;
insertPos->right = node;
}
if (temp != nullptr) {
if (temp->val > val) node->right = temp;
else node->left = temp;
}
return root;
}
};
二叉搜索树插入任何结点都可以在叶子结点找到插入位置,优化版:
class Solution {
public:
TreeNode* insertIntoBST(TreeNode* root, int val) {
if (root == nullptr) {
TreeNode* node = new TreeNode(val);
return node;
}
if (root->val > val) {
root->left = insertIntoBST(root->left, val);
}
if (root->val < val) {
root->right = insertIntoBST(root->right, val);
}
return root;
}
};
三、450删除二叉搜索树中的节点
模拟法。。递归写的少,太难想了,感觉很抽象
class Solution {
public:
TreeNode* pre = nullptr;
TreeNode* deleteNode(TreeNode* root, int key) {
TreeNode* cur = root;
while (cur) {
if (cur->val == key) break;
pre = cur;
if (cur->val > key) cur = cur->left;
else cur = cur->right;
}
//如果删除的结点不在树里,直接返回root
if (cur == nullptr) return root;
if (cur == root) {
if (cur->right == nullptr) return cur->left;
TreeNode* temp = cur->left;
root = cur->right;
cur = cur->right;
while (cur->left) {
cur = cur->left;
}
cur->left = temp;
return root;
}
//如果删除的结点为叶子结点,直接删掉就行
if (cur->left == nullptr && cur->right == nullptr) {
if (pre->val > cur->val) pre->left = nullptr;
else pre->right = nullptr;
}
//如果删除的结点的右子树不为空
if (cur->right) {
TreeNode* temp = cur->left;
if (pre->val > cur->val) {
pre->left = cur->right;
pre = pre->left;
}
else if (pre->val < cur->val) {
pre->right = cur->right;
pre = pre->right;
}
//temp插到右子树的最左叶子结点
while (pre->left) {
pre = pre->left;
}
pre->left = temp;
}
//如果删除的结点的右子树为空,左子树不为空
if (cur->left) {
if (pre->val > cur->val) {
pre->left = cur->left;
}
else {
pre->right = cur->left;
}
}
return root;
}
};
确实写的复杂了。在左右子树都不为空的那里多写了个条件判断,实际上是没有必要的,放左子树右子树都行。优化后的代码:
class Solution {
public:
TreeNode* deleteNode(TreeNode* root, int key) {
//没找到
if (root == nullptr) return root;
if (root->val == key) {
//叶子结点
if (root->left == nullptr && root->right == nullptr) {
delete root;
return nullptr;
}
//左空右不空
else if (root->left == nullptr) {
auto retNode = root->right;
delete root;
return retNode;
}
//左不空右空
else if (root->right == nullptr) {
auto retNode = root->left;
delete root;
return retNode;
}
//左右都不空
else {
TreeNode* cur = root->right;
while (cur->left) {
cur = cur->left;
}
cur->left = root->left;
return root->right;
}
}
if (root->val < key) {
root->right = deleteNode(root->right, key);
}
else {
root->left = deleteNode(root->left, key);
}
return root;
}
};