// 随机生成一个数组,实际情况中可以是远程获取的数据
function getArr() {
const arr = [];
for (let i = 0; i < 1000; i++) {
arr.push(Math.floor(Math.random() * arr.length));
}
return arr;
}
const arr = getArr();
// 二叉树节点
function Node(value) {
this.value = value;
this.left = null;
this.right = null;
}
// 往root为根节点添加节点
function addNode(root, num) {
if (root === null) return;
if (root.value === num) return;
if (root.value < num) {
// 目标值比当前值大
if (root.right === null) {
root.right = new Node(num);
} else {
addNode(root.right, num);
}
} else {
// 目标值比当前值小
if (root.left === null) {
root.left = new Node(num);
} else {
addNode(root.left, num);
}
}
}
// 构建二叉搜素树
function buildSearchTree(arr) {
if (arr === null || arr.length === 0) return null;
const root = new Node(arr[0]);
for (let i = 1; i < arr.length; i++) {
addNode(root, arr[i]);
}
return root;
}
const root = buildSearchTree(arr);
二、生成一个判断一棵树是否为平衡二叉树的方法
function getDeep(root) {
if (root === null) return -1;
let left = getDeep(root.left);
let right = getDeep(root.right);
return Math.max(left, right) + 1;
}
function isBalanceTree(root) {
if (root === null) return true;
let left = getDeep(root.left);
let right = getDeep(root.right);
if (Math.abs(left - right) > 1) {
return false; // 如果高度差大于1则不是
} else {
return isBalanceTree(root.left) && isBalanceTree(root.right); // 需要左子树和右子树都是平衡的
}
}
三、将一棵树变为平衡二叉树
function leftRotate(root) {
// 找到新根
let newRoot = root.right;
// 找到变化分支
let changeTree = root.right.left;
// 当前旋转节点的右节点为变化分支
root.right = changeTree;
// 新根的左节点为原根节点
newRoot.left = root;
return newRoot;
}
// 右单旋
function rightRotate(root) {
// 找到新根
let newRoot = root.left;
// 找到变化分支
let changeTree = root.left.right;
// 当前旋转节点的右节点为变化分支
root.left = changeTree;
// 新根的左节点为原根节点
newRoot.right = root;
return newRoot;
}
// 将一颗二叉树变为平衡二叉树
function changeToBalanceTree(root) {
if (isBalanceTree(root)) return root;
// 从底层往顶层做平衡
if (root.left !== null) root.left = changeToBalanceTree(root.left);
if (root.right !== null) root.right = changeToBalanceTree(root.right);
// 获取左右子树的深度
let leftDeep = getDeep(root.left);
let rightDeep = getDeep(root.right);
if (Math.abs(leftDeep - rightDeep) < 2) {
return root;
} else if (leftDeep > rightDeep) {
// 如果变化分支的深度大于非变化分支,需要先进行一次左旋
let changeTreeDeep = getDeep(root.left.right);
let noChangeTreeDeep = getDeep(root.left.left);
if (changeTreeDeep > noChangeTreeDeep) {
root.left = leftRotate(root.left);
}
// 左边比右边深,需要进行右单旋,然后看需不需要进行右右双旋
let newRoot = rightRotate(root);
newRoot.right = changeToBalanceTree(newRoot.right);
newRoot = changeToBalanceTree(newRoot);
return newRoot;
} else {
// 如果变化分支的深度大于非变化分支,需要先进行一次右旋
let changeTreeDeep = getDeep(root.right.left);
let noChangeTreeDeep = getDeep(root.right.right);
if (changeTreeDeep > noChangeTreeDeep) {
root.right = rightRotate(root.right);
}
// 右边比左边深,需要进行左单旋,然后看需不需要进行左左双旋
let newRoot = leftRotate(root);
newRoot.left = changeToBalanceTree(newRoot.left);
newRoot = changeToBalanceTree(newRoot);
return newRoot;
}
}
changeToBalanceTree(root);
console.log(isBalanceTree(root)); // true