这是二叉树参考图:
构建排序二叉树
function BinaryTree() {
var Node = function (key) {
this.key = key;
this.left = null;
this.right = null;
};
var root = null;
var insertNode = function (node, newNode) {
if (newNode.key < node.key) {
if (node.left === null) {
node.left = newNode;
} else {
insertNode(node.left, newNode);
}
} else if (newNode.key > node.key) {
if (node.right === null) {
node.right = newNode;
} else {
insertNode(node.right, newNode);
}
}
}
this.insert = function (key) {
var newNode = new Node(key);
if (root === null) {
root = newNode;
} else {
insertNode(root, newNode);
}
return root;
}
}
var nodes = [8, 3, 10, 1, 6, 14, 4, 7, 13];
var binaryTree = new BinaryTree();
nodes.forEach(key => {
binaryTree.insert(key);
})
上面是构建一个排序好的二叉树,下面是从构建好的排序二叉树中获取相关节点的信息,这就需要遍历,遍历有三种方法:中序遍历,前序遍历和后序遍历。
中序遍历排序
function BinaryTree() {
var Node = function (key) {
this.key = key;
this.left = null;
this.right = null;
};
var root = null;
var insertNode = function (node, newNode) {
if (newNode.key < node.key) {
if (node.left === null) {
node.left = newNode;
} else {
insertNode(node.left, newNode);
}
} else if (newNode.key > node.key) {
if (node.right === null) {
node.right = newNode;
} else {
insertNode(node.right, newNode);
}
}
}
this.insert = function (key) {
var newNode = new Node(key);
if (root === null) {
root = newNode;
} else {
insertNode(root, newNode);
}
return root;
}
//中序遍历
var inOrderTraverseNode = function(node,callback){
if(node){
inOrderTraverseNode(node.left,callback);
callback(node.key);
inOrderTraverseNode(node.right,callback);
}
}
this.inOrderTraverse = function(callback){
inOrderTraverseNode(root,callback);
}
}
var nodes = [8, 3, 10, 1, 6, 14, 4, 7, 13];
var binaryTree = new BinaryTree();
nodes.forEach(key => {
binaryTree.insert(key);
})
var callback = function(key){
console.log(key);
}
binaryTree.inOrderTraverse(callback);
中序遍历是先访问当前节点的左节点,然后访问当前节点自己,最后访问当前节点的右节点
前序遍历复制已有的二叉树
相比重新生成二叉树,通过前序遍历复制之前生成好的二叉树效率会更高。
function BinaryTree() {
var Node = function (key) {
this.key = key;
this.left = null;
this.right = null;
};
var root = null;
var insertNode = function (node, newNode) {
if (newNode.key < node.key) {
if (node.left === null) {
node.left = newNode;
} else {
insertNode(node.left, newNode);
}
} else if (newNode.key > node.key) {
if (node.right === null) {
node.right = newNode;
} else {
insertNode(node.right, newNode);
}
}
}
this.insert = function (key) {
var newNode = new Node(key);
if (root === null) {
root = newNode;
} else {
insertNode(root, newNode);
}
return root;
}
//中序遍历
var inOrderTraverseNode = function (node, callback) {
if (node) {
inOrderTraverseNode(node.left, callback);
callback(node.key);
inOrderTraverseNode(node.right, callback);
}
}
this.inOrderTraverse = function (callback) {
inOrderTraverseNode(root, callback);
}
//前序遍历
var preOrderTraverseNode = function (node, callback) {
if (node) {
callback(node.key);
preOrderTraverseNode(node.left, callback);
preOrderTraverseNode(node.right, callback);
}
}
this.preOrderTraverse = function (callback) {
preOrderTraverseNode(root, callback);
}
}
var nodes = [8, 3, 10, 1, 6, 14, 4, 7, 13];
var binaryTree = new BinaryTree();
nodes.forEach(key => {
binaryTree.insert(key);
})
var callback = function (key) {
console.log(key);
}
//这里调用不同的方法测试
binaryTree.preOrderTraverse(callback);
前序遍历是先访问当前节点自己,然后访问当前节点的左节点,最后访问当前节点的右节点。
后序遍历
后序遍历是先访问当前节点的左节点,然后访问当前节点的右节点,最后访问当前节点自己。
二叉树节点查找
- 查找最小值和最大值
- 查找某个给定的数值在二叉树中是否存在
function BinaryTree() {
var Node = function (key) {
this.key = key;
this.left = null;
this.right = null;
};
var root = null;
var insertNode = function (node, newNode) {
if (newNode.key < node.key) {
if (node.left === null) {
node.left = newNode;
} else {
insertNode(node.left, newNode);
}
} else if (newNode.key > node.key) {
if (node.right === null) {
node.right = newNode;
} else {
insertNode(node.right, newNode);
}
}
}
this.insert = function (key) {
var newNode = new Node(key);
if (root === null) {
root = newNode;
} else {
insertNode(root, newNode);
}
return root;
}
//中序遍历
var inOrderTraverseNode = function (node, callback) {
if (node) {
inOrderTraverseNode(node.left, callback);
callback(node.key);
inOrderTraverseNode(node.right, callback);
}
}
this.inOrderTraverse = function (callback) {
inOrderTraverseNode(root, callback);
}
//前序遍历
var preOrderTraverseNode = function (node, callback) {
if (node) {
callback(node.key);
preOrderTraverseNode(node.left, callback);
preOrderTraverseNode(node.right, callback);
}
}
this.preOrderTraverse = function (callback) {
preOrderTraverseNode(root, callback);
}
//查找最小值
var minNode = function (node) {
if (node) {
while (node && node.left !== null) {
node = node.left;
}
return node.key;
}
return null;
}
this.min = function () {
return minNode(root);
}
//查找最大值
var maxNode = function (node) {
if (node) {
while (node && node.right !== null) {
node = node.right;
}
return node.key;
}
return null;
}
this.max = function () {
return maxNode(root);
}
//查找给定值的节点
//在searchNode递归前面加return,退出上一轮 `searchNode`,以免产生调用栈,如果不加 `return` 那在结束之后是是会层层回退到第一次调用,返回其结果。
var searchNode = function (node, key) {
if (!node) {
return false;
}
if (key < node.key) {
return searchNode(node.left, key)
} else if (key > node.key) {
return searchNode(node.right, key);
} else {
return true;
}
}
this.search = function (key) {
return searchNode(root, key);
}
}
var nodes = [8, 3, 10, 1, 6, 14, 4, 7, 13];
var binaryTree = new BinaryTree();
nodes.forEach(key => {
binaryTree.insert(key);
})
var callback = function (key) {
console.log(key);
}
//这里调用不同的方法测试
binaryTree.preOrderTraverse(callback);
console.log(binaryTree.min());
console.log(binaryTree.max());
console.log(binaryTree.search(7));