代码随想录刷题——二叉树篇(二十)

450. 删除二叉搜索树中的节点
递归法(二叉搜索树):

cpp 复制代码
class Solution{
public:
	TreeNode* deleteNode(TreeNode* root, int key){
		if(!root) return root;
		if(key==root->val){
			if(!root->left&&!root->right){
				delete root;
				return NULL;
			}
			else if(!root->left){
				TreeNode* rn=root->right;
				delete root;
				return rn;
			}
			else if(!root->right){
				TreeNode* ln=root->left;
				delete root;
				return ln;
			}
			else{
				TreeNode* tn=root->right;
				while(tn->left){
					tn=tn->left;
				}
				tn->left=root->left;
				TreeNode* tmp=root;
				root=root->right;
				delete tmp;
				return root;
			}
		}
		if(key<root->val) root->left=deleteNode(root->left,key);
		if(key>root->val) root->right=deleteNode(root->right,key);
		return root;
	}
};

递归法(普通二叉树):

cpp 复制代码
class Solution{
public:
	TreeNode* deleteNode(TreeNode* root,int key){
		if(!root) return NULL;
		if(root->val==key){
			if(!root->right) return root->left;
			TreeNode* tn=root->right;
			while(tn->left){
				tn=tn->left;
			}
			swap(root->val,tn->val);
		}
		root->left=deleteNode(root->left,key);
		root->right=deleteNode(root->right,key);
		return root;
	}
};

迭代法:

cpp 复制代码
class Solution{
private:
	TreeNode* deleteOneNode(TreeNode* root){
		if(!root) return root;
		else if(!root->left) return root->right;
		else if(!root->right) return root->left;
		else{
			TreeNode* tn=root->right;
			while(tn->left){
				tn=tn->left;
			}
			tn->left=root->left;
			return root->right;
		}
	}
public:
	TreeNode* deleteNode(TreeNode* root,int key){
		if(!root) return root;
		TreeNode* cur=root;
		TreeNode* pre=NULL;
		while(cur){
			if(key==cur->val) break;
			pre=cur;
			if(key<cur->val) cur=cur->left;
			else if(key>cur->val) cur=cur->right;
		}
		if(!pre) return root;
		else if(pre->left==cur) pre->left=deleteOneNode(cur);
		else if(pre->right==cur) pre->right=deleteOneNode(cur);
		return root;
	} 
};

其他:

(1)递归新理解:有返回值的递归存在一个上层类别节点选择递归路径 、下层类别节点向上递出返回值 、上层类别节点接受返回值 的过程。所以考虑的时候可以用从下向上 和从上向下的两种方式进行。

(2)判断时分支容易写错的问题:

cpp 复制代码
if(!root->left&&!root->right){
    delete root;
	return NULL;
}
else if(root->left){
	TreeNode* ln=root->left;
	delete root;
	return ln;
}
else if(root->right){
	TreeNode* rn=root->right;
	delete root;
	return rn;
}
else{
	TreeNode* tn=root->right;
	while(tn->left){
		tn=tn->left;
	}
	tn->left=root->left;
	TreeNode* tmp=root;
	root=root->right;
	delete tmp;
	return root;
}

对于本题来说,上面的分支是错误的,因为分支1是左右双空,原本想要的分支4是左右都非空,但此时分支2和分支3两个分支与分支4有重合。下面的分支则是正确的:

cpp 复制代码
if(!root->left&&!root->right){
	delete root;
	return NULL;
}
else if(!root->left){
	TreeNode* rn=root->right;
	delete root;
	return rn;
}
else if(!root->right){
	TreeNode* ln=root->left;
	delete root;
	return ln;
}
else{
	TreeNode* tn=root->right;
	while(tn->left){
		tn=tn->left;
	}
	tn->left=root->left;
	TreeNode* tmp=root;
	root=root->right;
	delete tmp;
	return root;
}

这里对自己来说有些容易写错,记录一下,一定要保证if else分支之间的情况是完全隔离的

(3)对于递归法 来说,访问操作 通常发生在当前层 ,而对于迭代法 来说,访问 通常发生在上一层

对于递归法 来说,访问和操作 通常发生在一起 ,而对于迭代法 来说,访问和操作 可以分成两步 ,操作 可以单独写一个函数

(4)二叉搜索树的迭代法遍历访问特定值的节点

cpp 复制代码
while(cur){
	if(key==cur->val) break;
	pre=cur;
	if(key<cur->val) cur=cur->left;
	else cur=cur->right;
}

(5)pre 在二叉搜索树 的迭代法寻找中有两个作用:

a.一是判断是否停在根节点

b.二是停在非根节点 的时候,找前一个节点的指针 进行操作

相关推荐
yi0116 小时前
LeetCode 219:存在重复元素 II——哈希表记录“最近一次出现的位置”
数据结构·人工智能·笔记·python·算法·leetcode·哈希表
灯澜忆梦9 小时前
【面向对象编程C++】| 基础语法
java·c++·算法
小蒋观天下9 小时前
专项方案:大场景港口AI安防、多干扰环境下的算法调优与落地实操
人工智能·深度学习·算法·安全·机器学习·计算机视觉·ai大模型
Evand J9 小时前
【电机滤波例程5】渐消因子自适应扩展卡尔曼滤波(EKF),MATLAB。PMSM负载突变下的状态估计。附下载链接
算法·matlab
H.莓飛9 小时前
【数据结构】二叉树_OJ题
linux·开发语言·数据结构·算法
好想像大佬一样能够ak所有10 小时前
Leetcode35.搜索插入位置
数据结构·算法·leetcode
aqiu11111110 小时前
【C++算法打怪专栏】LeetCode 165. 比较版本号(双指针与字符串流法)
c++·算法·leetcode
黄金龙PLUS10 小时前
如何基于置换算法来设计对称加密算法
算法·网络安全·密码学·哈希算法·同态加密
不会就选b10 小时前
算法日常・每日刷题--<动态规划>14
算法
赛博守夜人11 小时前
跨境业务与出海合规之九:海外买量投放与营销虚假流量(Ad Fraud):跨国机房群控与归因欺诈识别算法
算法·安全