235. 二叉搜索树的最近公共祖先
从数学角度来说,本体应用了搜索二叉树的特性:所有节点唯一且所有左侧节点小于右侧节点,这样当我们确定了所给的两个节点(p,q)时,只需要找到第一个节点对应的值处在(p,q)区间的节点就是我们要找的节点。这样并不会出现找的节点不够深,因为它上一层的节点必定大于或小于这一整个枝的节点,不满足条件。据此可以确定单层递归的逻辑:如果当前节点值比q,p都大,向左递归,比p,q都小,向右递归。
if(root->val>p->val&&root->val>q->val){
TreeNode* left=traversal(root->left,p,q);
return left;
}
if(root->val<p->val&&root->val<q->val){
TreeNode* right=traversal(root->right,p,q);
return right;
}
同时每一层返回下一层递归回返回的节点(直到出现符合的节点,返回其地址),因此返回参数设置为
TreeNode*traversal(TreeNode* root,TreeNode* p,TreeNode* q){
701.二叉搜索树中的插入操作
同样的二叉搜索树思路,若插入的值大于当前值向右递归,小于当前值,向左递归
if(root->val>val){
traversal(root->left,val);
}
if(root->val<val){
traversal(root->right,val);
}
每次不需要返回值,故函数类型为void
void traversal(TreeNode* root,int val){
同时定义一个全局变量parent用来定义上一层的节点,这样每到一层,先判断,若为空节点,则开始在上一层节点后安插,若不是,则将当层节点填入parent开始下一层。
TreeNode* parent;
void traversal(TreeNode* root,int val){
if(root==NULL){
TreeNode* cur=new TreeNode(val);
if(parent->val>val){
parent->left=cur;
}
else{
parent->right=cur;
}
return;
}
450.删除二叉搜索树中的节点
删除二叉搜索树的节点,总的来说,我觉得有两个难点:首先便是若是被删除的节点有左右子系节点应该怎么办,还有就是函数返回值问题:最终肯定要返回root,那递归时每一次返回什么呢?
首先第一点,当前节点删除后,右子树补上,将左子树整个剪下来,贴到右子树最左侧节点上。
f(root->val==key){
if(root->left==NULL&&root->right==NULL){
delete root;
return NULL;
}
else if(root->left==NULL&&root->right!=NULL){
auto temp=root->right;
delete root;
return temp;
}
else if(root->left!=NULL&&root->right==NULL){
auto temp=root->left;
delete root;
return temp;
}
else{
auto rightLeft=root->right;
while(rightLeft->left!=NULL){
rightLeft=rightLeft->left;
}
rightLeft->left=root->left;
auto temp=root->right;
delete root;
return temp;
}
第二点就是每一次将当前节点的左右指针指向递归后的返回值,这样在更新整个二叉树的时候就会每一个节点重新定义左右子枝,在最后返回root就可以了。
f(root->val>key)root->left=deleteNode(root->left,key);
if(root->val<key)root->right=deleteNode(root->right,key);
return root;