- 二叉搜索树中的插入操作
- 思路1:递归
要往树中插入一个节点,自然要先找到插入的位置,再将其和父节点联系起来即可;
对于二叉搜索树,特点是有序;当需要插入元素,自然找到插入位置时需要new一个结点,那如何使该结点和父节点产生联系呢?
①利用返回值(只处理当前节点)
//二叉搜索树本身有序,因此无需遍历整棵树,插入位置根据当前节点和val的大小关系可以判断出接下来往哪走
//通过递归函数返回值完成新加入节点的父子关系赋值操作,下一层将加入节点返回,本层用root->left或者root->right将其接住
TreeNode* insertIntoBST(TreeNode* root, int val) {
if (root == NULL) return new TreeNode(val); //找到val本该出现的位置:new一个结点返回
//下面某个分支接住
if (root->val > val) root->left = insertIntoBST(root->left, val);//接住
else root->right = insertIntoBST(root->right, val);//接住
return root;
}
②直接在当前节点把它的孩子都判断好(无需返回值)
class Solution {
private:
//相当于提前把当前节点为空的情况由它的父亲处理了,因此函数开头无需判空(只要在第一次调用递归函数时,进行一次判空就行)
void serachPos(TreeNode* cur, int val) {
if(cur->val > val) {
if(cur->left == NULL) cur->left = new TreeNode(val);
else serachPos(cur->left, val);
}
else {
if(cur->right == NULL) cur->right = new TreeNode(val);
else serachPos(cur->right, val);
}
}
public:
TreeNode* insertIntoBST(TreeNode* root, int val) {
if (root == NULL) return new TreeNode(val); //递归函数的单层逻辑中没有判空,默认只处理非空结点,因此在开始的第一步需要排除掉空
serachPos(root, val);
return root;
}
};
- 思路2:迭代
//额外维护一个parent,就像单链表一样
class Solution {
public:
TreeNode* insertIntoBST(TreeNode* root, int val) {
if (root == NULL) return new TreeNode(val);
TreeNode* cur = root;
TreeNode* parent = cur;
while(cur) {
parent = cur;
if(cur->val > val) cur = cur->left;
else cur = cur->right;
}
if(parent->val > val) parent->left = new TreeNode(val);
else parent->right = new TreeNode(val);
return root;
}
};
- 总结:
- 搜索树自带顺序,需要查找某个位置时可以一条线找下去,无需整棵树遍历;
- 当需要与父节点产生联系时:递归函数有返回值:就只处理当前节点;无返回值:就提前把自己的孩子处理了
- 搜索树中两节点之间的关系,常借助pre,parent