二叉排序树
一、什么是二叉排序树
二叉排序树也叫二叉查找树,二叉排序树或者是一棵空树,或者是具有下列性质的二叉树:
(1)若它的左子树不空,则左子树的所有节点的值均小于它的根结点的值。
(2)若它的右子树不空,则右子树的所有节点的值均大于它的根节点的值。
(3)它的左右子树也分别为二叉排序树。
二、二叉排序树的一些操作
1、查找元素
1.1递归查找
递归查找的方法的思想:
是首先判断这这棵树是否为空,如果为空,则表示该树上没有该值,否则判断该节点值是否等于要查找的节点,如果等于,则返回该节点,否则判断该节点的值与需要查找的值的大小关系,如果大于需要查找的节点,则递归查找左子树,否则递归查找右子树。
function find_BST(BT, key) { //在二叉搜索树种查找某值,返回该节点(递归法)
if (BT == null) {
console.log("搜索树中无查找的值");
}
else if (BT.data == key) {
return BT;
}
else if (BT.data > key) {
return find_BST(BT.left, key);
}
else {
return find_BST(BT.right, key);
}
}
1.1非递归查找
function unrecur_find_BST(BT, key) //在二叉搜索树中查找值,返回该节点(非递归)
{
while (BT) {
if (BT.data == key) {
return BT;
}
else if (BT.data > key) {
BT = BT.left;
}
else {
BT = BT.right;
}
}
console.log("搜索树中无查找的值");
}
2、查找最大节点
由二叉搜索树的性质可以知道,最大的节点就是最右边的节点,所以只要不断往右找到最右边的那个节点就是最大节点2.1递归查找最大节点
function max_BST(BT) { //返回二叉搜索树的最大节点(递归法)
if (BT == null) {
console.log("搜索树为空");
}
else if (BT.right != null) {
return max_BST(BT.right);
}
else {
return BT;
}
}
2.2非递归查找最大节点
function unrecur_max_BST(BT) //返回二叉搜索树的最大节点(非递归法)
{
if (BT == null) {
console.log("搜索树为空");
}
while (BT.right) {
BT = BT.right;
}
return BT;
}
3、查找最小节点
由二叉搜索树的性质可以知道,最小的节点就是最左边的节点,所以只要不断往左找到最左边的那个节点就是最小节点3.1递归查找最小节点
function min_BST(BT) //返回二叉搜索树的最小节点(递归法)
{
if (BT == null) {
console.log("搜索树为空");
}
else if (BT.left != null) {
return min_BST(BT.left);
}
else {
return BT;
}
}
3.2非递归查找最小节点
function unrecur_min_BST(BT) //返回二叉搜索树的最小节点(非递归法)
{
if (BT == null) {
console.log("搜索树为空");
}
while (BT.left) {
BT = BT.left;
}
return BT;
}
3、插入节点
首先判断树是否为空,如果为空,则创建一个新的节点,然后判断插入的节点的值,如果大于当前根,则向右子树方向插入,反之向左子树方向插入。3.1递归法插入节点
function insert_BST(BT, key)//用递归的方式插入节点到二叉搜索树
{
if (!BT) {
BT = new BTNode();
BT.left = BT.right = null;
BT.data = key;
}
else {
if (key > BT.data) {
BT.right=insert_BST(BT.right, key);
}
else {
BT.left= insert_BST(BT.left, key);
}
}
return BT;
}
3.2非递归插入节点
function unrecur_insert_BST(BT, key)//非递归方式插入节点到二叉树
{
while (BT) {
if (BT.data < key) {
if (BT.right == null) {
BT.right = new BTNode();
BT.right.left = BT.right.right = null;
BT.right.data = key;
return;
}
BT = BT.right;
}
else {
if (BT.left == null) {
BT.left = new BTNode();
BT.left.left = BT.left.right = null;
BT.left.data = key;
return;
}
BT = BT.left;
}
}
BT = new BTNode();
BT.left = BT.right = null;
BT.data = key;
return BT;
}
4、删除节点
二叉搜索树的节点删除有一下几种情况(1)删除的节点没有左右孩子,则直接将其父节点指向它的指针删除。
(2)删除节点有一个左右孩子,则直接用它的左右孩子替代它
(3)删除的节点左右孩子都有,这种情况比较麻烦,所以我们可以想到可以把这种情况转化为前两种情况,可以想到我们可以用右子树的最小值或者左子树的最大值来替换这个元素,然后就可以把删除这个元素转化成删除右子树的最小值或者左子树的最大值,而右子树的最小值没有左子树,左子树的最大值没有右子树,所以可以转化为情况(1)或者(2)
function delete_BST(BT, key) {
if (!BT) {
console.log("要删除的节点未找到");
}
else if (BT.data > key) {
BT.left = delete_BST(BT.left, key);
}
else if (BT.data < key) {
BT.right = delete_BST(BT.right, key);
}
else {
if (BT.left && BT.right) {
let tmp = max_BST(BT);
BT.data = tmp.data;
delete_BST(BT.right, BT.data);
}
else {
if (!BT.left) {
BT = BT.right;
}
else if (!BT.right) {
BT = BT.left;
}
}
}
return BT;
}