一、二叉树
二叉树又称二叉堆,可用数组的结构实现,比如堆排序,二叉树的遍历。
前序遍历:中左右
function preOrder (root) {
let res = [];
let stack = [root];
while (stack.length > 0) {
let node = stack.pop();
res.push(node.value);
if (node.right) {
stack.push(node.right);
}
if (node.left) {
stack.push(node.left);
}
}
return res;
}
中序遍历:左中右
function inOrder (root) {
let res = [];
let stack = [];
while (stack.length > 0 || root) {
while (root) {
stack.push(root);
root = root.left;
}
root = root.pop();
res.push(root.value);
root = root.right;
}
return res;
}
后序遍历:左右中
function lastOrder (root) {
let res = [];
let stack = [root];
while (stack.length > 0) {
let node = stack.pop();
res.unshift(node.value);
if (node.left) {
stack.push(node.left);
}
if (node.right) {
stack.push(node.right);
}
}
return res;
}
广度遍历
function BreadthFirstSearch(tree) {
let res = [];
let queue = [tree];
while (queue.length > 0) {
let node = queue.shift();
res.push(node.value);
if (node.left) {
queue.push(node.left);
}
if (node.right) {
queue.push(node.right);
}
}
return res;
}
二、排序二叉树
插入
function newNode (val) {
this.value = value;
this.left = null;
this.right = null;
}
// 插入
function insertNode (root, key) {
if (!root) {
root.value = key;
return true;
}
if (key < root.value) {
if (root.left) {
insertNode(root.left, key);
} else {
root.left = new newNode(key);
}
} else if (key > root.value) {
if (root.right) {
insertNode(root.right, key);
} else {
root.right = new newNode(key);
}
} else {
return false;
}
return true;
}
创建
function create (arr) {
let tree = new newNode(null);
for (let i = 0; i < arr.length; i++) {
insertNode(tree, arr[i]);
}
return tree;
}
遍历
function inOrder (root) {
if (root) {
inOrder(root.left);
console.log(root.value);
inOrder(root.right);
}
}
删除
function deleteNode (root, key) {
if (!root) {
return root;
}
if (key < root.value) {
root.left = deleteNode(root.left, key);
} else if (key > root.value) {
root.right = deleteNode(root.right, key);
} else {
if (root.left === null && root.right === null) {
root = null;
} else if (root.left === null && root.right) {
root = root.right;
} else if (root.right === null && root.left) {
root = root.left;
} else {
let preNode = root.left;
while (preNode.right) {
preNode = preNode.right;
}
root.value = preNode.value;
root.left = deleteNode(root.left, preNode);
}
}
return root;
}
三、平衡二叉查找树(AVL)
插入
function newNode (val) {
this.value = value;
this.left = null;
this.right = null;
}
// 插入
function insertNode (tree, key) {
if (!tree) {
tree.value = key;
return tree;
}
if (key < tree.value) {
if (tree.left) {
tree.left = insertNode(tree.left, key);
tree = adjustBalanceTree(tree);
} else {
tree.left = new newNode(key);
}
} else if (key > tree.value) {
if (tree.right) {
tree.right = insertNode(tree.right, key);
tree = adjustBalanceTree(tree);
} else {
tree.right = new newNode(key);
}
}
return tree;
}
function adjustBalanceTree (tree) {
if (!tree) {
return tree;
}
if (getTreeHeight(tree.left) - getTreeHeight(tree.right) > 1) {
if (getTreeHeight(tree.left.left) - getTreeHeight(tree.left.right) >= 1) {
tree = balanceLL(tree);
} else {
tree = balanceLR(tree);
}
} else if (getTreeHeight(tree.right) - getTreeHeight(tree.left) > 1) {
if (getTreeHeight(tree.right.right) - getTreeHeight(tree.right.left) >= 1) {
tree = balanceRR(tree);
} else {
tree = balanceRL(tree);
}
}
return tree;
}
function getTreeHeight (tree) {
if (!tree) {
return 0;
}
return Math.max(getTreeHeight(tree.left), getTreeHeight(tree.right)) + 1;
}
function balanceLL (node) {
let tmp = node.left;
node.left = tmp.right;
tmp.right = node;
return tmp;
}
function balanceRR (node) {
let tmp = node.right;
node.right = tmp.left;
tmp.left = node;
return tmp;
}
function balanceLR (node) {
node.left = balanceRR(node.left);
return balanceLL(node);
}
function balanceRL (node) {
node.right = balanceLL(node.right);
return balanceRR(node);
}
删除
function deleteNode (tree, key) {
if (!tree) {
return tree;
}
if (key < tree.value) {
tree.left = deleteNode(tree.left, value);
tree = adjustBalanceTree(tree);
} else if (key > tree.value) {
tree.right = deleteNode(tree.right, value);
tree = adjustBalanceTree(tree);
} else {
if (tree.left === null && tree.right === null) {
tree = null;
} else if (tree.left === null && tree.right) {
tree = tree.right;
} else if (tree.right === null && tree.left) {
tree = tree.left;
} else {
let preNode = tree.left;
while (preNode.right) {
preNode = preNode.right;
}
tree.value = preNode.value;
tree.left = deleteNode(tree.left, preNode);
}
tree = adjustBalanceTree(tree);
}
return tree;
}