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

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.二是停在非根节点 的时候,找前一个节点的指针 进行操作

相关推荐
BothSavage14 小时前
Trae远程开发中DeepSeek自定义模型4054错误的排查与修复
算法
小林ixn14 小时前
从暴力到KMP:一道题彻底搞懂字符串匹配的前世今生
算法
烬羽16 小时前
字符串算法入门:从反转字符串到回文判断,面试不再慌
算法·面试
先吃饱再说1 天前
判断回文字符串,从一行代码到双指针优化
算法
黄敬峰1 天前
深入理解算法核心:从递归思想、数组扁平化到快速排序
算法
得物技术1 天前
从狂野代码到按目标生产:得物推荐 AI Harness 的工程化实践|AICon 演讲整理
人工智能·算法·架构
AI小老六2 天前
SkillOpt 架构拆解:把 Skill 文本当参数,用执行轨迹训练 Agent
后端·算法·ai编程
胡萝卜术2 天前
从“分数打架”到“排名投票”:为什么你的ChatBI必须用RRF?
算法·设计模式·面试
Asize2 天前
初识DFS 与 BFS:递归、队列与图遍历
算法