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

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

相关推荐
绝知此事几秒前
【算法突围 01】线性结构与哈希表:后端开发的收纳术
java·数据结构·算法·面试·jdk·散列表
碧海银沙音频科技研究院8 分钟前
通话AEC与语音识别AEC的软硬回采链路
深度学习·算法·语音识别
csdn_aspnet1 小时前
Python 算法快闪 LeetCode 编号 70 - 爬楼梯
python·算法·leetcode·职场和发展
m0_629494734 小时前
LeetCode 热题 100-----26.环形链表 II
数据结构·算法·leetcode·链表
壹号用户4 小时前
用队列实现栈
数据结构·算法
做人求其滴4 小时前
面试经典 150 题 380 274
c++·算法·面试·职场和发展·力扣
daad7774 小时前
记一组无人机IMU传感器数据
算法
计算机安禾4 小时前
【c++面向对象编程】第42篇:模板特化与偏特化:为特定类型定制实现
开发语言·c++·算法
小O的算法实验室4 小时前
2026年KBS,流形感知强化学习差分进化算法+不规则3D无人机路径规划,深度解析+性能实测
算法·智能算法·智能算法改进