题目:https://leetcode-cn.com/problems/insert-into-a-binary-search-tree/submissions/
思路一:递归(函数有返回值)
分析:二叉搜索树要插入一个新值, 只要遍历二叉搜索树,找到空节点插入元素就可以了;让插入的新节点的值与根节点相比,如果要插入新节点的值比较大,递归左子树,否则递归右子树;直到遇到空节点,创建新节点,将新节点返回
步骤:
递归三部曲:
-
函数参数和返回值
因为要插入新值,参数为根节点和值; 可以利用返回值完成新加入的节点与其父节点的赋值操作 ;所以函数返回值为节点。
-
终止条件
如果节点为空,创建新节点,然后将其返回
-
单层逻辑
如果节点值比目标值大,就递归左子树,
如果节点值比目标值小,就递归右子树
「到这里,大家应该能感受到,如何通过递归函数返回值完成了新加入节点的父子关系赋值操作了,下一层将加入节点返回,本层用root->left或者root->right将其接住」。
class Solution {
public:
TreeNode* insertIntoBST(TreeNode* root, int val) {
if (root == NULL) {
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;
}
};
思路二:递归(函数没有返回值)
分析:这道题的意图是让新节点成为某个叶子节点的子节点,这就要求找到要插入的位置后,还需要知道父节点,所以需要把父节点记录下来,最常用的方式是定义一个指针变量,每递归一次,就将前一个节点保存下来。
class Solution {
private:
TreeNode*parent;//用于保存父节点
void travesal(TreeNode*cur,int val)
{
if(cur==NULL)
{
TreeNode*node=new TreeNode(val);
if(val>parent->val)
parent->right=node;
else
{
parent->left=node;
}
return ;
}
parent=cur;//记录父节点
if(cur->val>val)
{
travesal(cur->left,val);
}
else {
travesal(cur->right,val);
}
}
public:
TreeNode* insertIntoBST(TreeNode* root, int val) {
if(root==NULL)
{
parent =new TreeNode(val);
return parent;
}
travesal(root,val);
return root;
}
};
``思路三:迭代
分析:插入新节点,因为是二叉搜索树,需要将插入的新节点的位置找到,怎么找?比较新节点的大小和当钱节点的大小,大就遍历左子树,小就遍历右子树(为啥不考虑相等,因为题目要求节点值都不同)并且将当前节点记录下来,直到遇到空节点停止
class Solution {
public:
TreeNode* insertIntoBST(TreeNode* root, int val) {
if(root==NULL)
{
TreeNode*root=new TreeNode(val);
return root;
}
TreeNode*cur=root;
TreeNode*parent =NULL;
while(cur)
{
parent=cur;
if(cur->val>val)
cur=cur->left;
else
{
cur=cur->right;
}
}
TreeNode*node=new TreeNode(val);
if(parent->val>val)
{
parent->left=node;
}
else
{
parent->right=node;
}
return root;
}
};