定义
1.若任意节点的左子树不空,则左子树上所有结点的值均小于它的根结点的值。
2.若任意节点的右子树不空,则右子树上所有结点的值均大于它的根结点的值。
3.任意节点的左、右子树也分别为二叉查找树。
4.没有键值相等的节点。
二叉树的遍历
先序遍历:输出的根的关键词位于左子树的关键字值和右子树的关键字值之前。
//方法一:递归法(一)
var preorderTraversal=function(root){
return root?[root.val,preorderTraversal(root.left),preorderTraversal(root.right)]:[];
};
//递归法(二)
var preorderTraversal=function(root){
let result=[];
var preorderTraverseNode=function(node){
if(node){
result.push(node.val);
preorderTraverseNode(node.left);
preorderTraverseNode(node.right);
}
}
preorderTraverseNode(root);
return result;
};
//迭代法
var preorderTraversal=function(root){
const list=[];
const stack=[];
if(root) stack.push(root);
while(stack.length>0){
const curNode=stack.pop();
list.push(curNode.val);
if(curNode.right){ //栈的先进后出,curNode.right节点先push入栈,curNode.left节点先出栈
stack.push(curNode.right);
}
if(cueNode.left){
stack.push(curNode.left);
}
}
return list;
};
中序遍历:输出的根的关键词位于左子树的关键字值和右子树的关键字值之间。
后序遍历:输出的根的关键词位于左子树的关键字值和右子树的关键字值之后。
二叉搜索树的基本操作
搜索
方法一:递归法
var searchBST=function(root,val){
if(!root) return root;
if(val===root.val) return root;
if(val<root.val) return searchBST(root.left,val);
if(val>root.val) return searchBST(root.right,val);
return null;
}
方法二:迭代法
var searchBST = function(root, val) {
if (!root) return null;
while(root) {
if (root.val === val) {
return root;
} else if (root.val > val) {
root = root.left;
} else if (root.val < val) {
root = root.right;
}
}
return null; //return root也可以,因为若二叉树中找不到val,最后赋值给root的值为null
};
时间复杂度 | 空间复杂度 | |
---|---|---|
递归法 | ||
迭代法 |
插入
var insertIntoBST = function(root, val) {
if (!root) {
return new TreeNode(val);
}
while (!root) {
if (val < root.val) {
if (!root.left) {
root.left = new TreeNode(val);
break;
} else {
root = root.left;
}
} else {
if (!root.right) {
root.right = new TreeNode(val);
break;
} else {
root = root.right;
}
}
}
return root;
};
时间复杂度 | 空间复杂度 | |
---|---|---|
迭代法 |
删除
var deleteNode=function(root,key){
if(!root) return null;
if(key<root.val){
root.left=deleteNode(root.left,key);
}else if(key>root.val){
root.right=deleteNode(root.right,key);
}else if(root.val===key){
if(!root.left && !root.right){
root=null;
}else if(root.left){
root.val=predecessor(root); //将左子树中最大元素获取并替代当前root
root.left=deleteNode(root.left,root.val); //将左子树中最大元素从左子树中删除,并更新当前root.left节点
}else if(root.right){
root.val=successor(root); //将右子树中最小元素获取并替代当前root
root.right=deleteNode(root.right,root.val); //将右子树中最小元素从左子树中删除,并更新当前root.right节点
}
}
return root;
};
//获取根节点左子树中最大元素
function predecessor(root){
if(!root) return null;
root=root.left;
while(root.right){
root=root.right;
}
return root.val;
}
//获取根节点右子树中最小元素
function successor(root){
if(!root) return null;
root=root.right;
while(root.left){
root=root.left;
}
return root.val;
}
时间复杂度 | 空间复杂度 | |
---|---|---|
迭代法 |
最大关键词元素和最小关键词元素
//最大关键词元素
var maxBST=function(root){
if(!root) return null;
while(root.right){
root=root.right;
}
return root.val;
}
//最小关键词元素
var minBST=function(root){
if(!root) return null;
while(root.left){
root=root.left;
}
return root.val;
}
后继和前驱
后继:中序遍历中相对当前节点的下一个
前驱:中序遍历中相对当前节点的上一个