private _ergodic(node: BNod): Array<NodeKey> {
let ans: Array<NodeKey> = [];
return ans.concat(node.left ? this._ergodic(node.left) : [], [node.key], node.right ? this._ergodic(node.right) : []);
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Binary Tree</title>
</head>
<body>
<script>
/**
* 二叉排序树
* 新插入的数据只是增加在原先的树上(新加入的结点找到一个位置,作为原先树上某个结点的孩子结点)
* 并不会破坏之前已形成的树
*/
var Node = function(key) {
this.key = key;
this.left = null;
this.right = null;
}; // var Node end
// nodes数组存储一下待排序的数据
var nodes = [
8,
3,
10,
1,
6,
14,
4,
7
];
// 新建一个排序树对象,是个函数对象
var binaryTree = new BinaryTree();
// 利用数组的forEach函数,依次处理数组中的数据,按下标
nodes.forEach(function(key) {
// 对于数组中的每一个值,进行二叉排序树的插入操作
binaryTree.insert(key);
});
//
var callback = function(key) { // 1
console.log(key);
}
binaryTree.inOrderTraverse(callback); // 1
function BinaryTree() {
var root = null;
// 将数组转换为二叉排序树
this.insert = function(key) {
var newNode = new Node(key);
if(root === null) {
root = newNode;
} else {
insertNode(root, newNode);
}
};
var insertNode = function(node, newNode) { // 递归地进行节点的插入
if(newNode.key < node.key) { // 如果新节点的值小于这个节点的父节点
if(node.left === null) {
// 如果父节点左孩子节点为空,则将新节点置为左孩子节点
node.left = newNode;
} else {
insertNode(node.left, newNode);
}
} else {
if(node.right === null) {
node.right = newNode;
} else {
insertNode(node.right, newNode);
}
}
}; // var insertNode end
// 中序遍历
this.inOrderTraverse = function(callback) { // callback是一个输出语句方法参数
inOrderTraverseNode(root, callback);
};
var inOrderTraverseNode = function(node, callback) { // node节点为根节点
if(node !== null) { // 如果根节点不为空,即树存在时,进行先左,在中,在右,并递归
inOrderTraverseNode(node.left, callback);
// 输出节点中的key值
callback(node.key);
// 这是外部的一个函数 var callback = function(key) 这里的意思是,上一句进入左子树,如果上一句的结点没有左子树的话,就打印是一个结点
/**
*
*inOrderTraverse中的callback参数的意义何在?
*睡了一觉,自己悟出来了。传入的callback,实际上就是老师定义的callback函数,
*因为老师的callback函数是定义在binarytree外部的,所以他把这个函数传进去,以便后续调用。
*我自己的代码,把callback函数定义在binarytree内部了,所以我不传callback参数是没有任何问题的,但是我的callback函数在其它地方就无法调用了。...
*
*callback只是一个引用,你也可以改成其他名字。为什么要用callback是因为程序员的习惯吧,大家一看就知道这里是一个回调函数。
*var声明的函数和this来声明的函数作用域不一样,var声明的在外面无法调用才对,你可以试试,我没验证。。。。。。。...
*/
inOrderTraverseNode(node.right, callback);
}
};
}
</script>
</body>
</html>
var inOrderTraverseNode = function (node,callback){
if(node!==null){
inOrderTraverseNode(node.left,callback);
callback(node.key);
inOrderTraverseNode(node.right,callback);
}
}
this.inOrderTraverse = function(callback){
inOrderTraverseNode(root,callback);
}
};
var nodes=[8,3,1,6,14,4,7,13];
var binaryTree=new BinaryTree();
nodes.forEach(function(key){
binaryTree.insert(key);
});
var callback=function(key){
console.log(key);
}
binaryTree.inOrderTraverse(callback);
function(callback){
}
当我们要输出某一个节点的值得时候,我们就把这个节点的值传入这个回调函数中,让这个回调函数决定怎么输出出来
中序遍历---先找左节点,然后父节点,最后右节点
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>JavaScript二叉树中序算法</title>
</head>
<body>
<script>
function BinaryTree() {
//初始化root根为空值
var root = null;
//将传入值添加this.key,this.left,this.right属性
var Node = function (key) {
this.key = key;
this.left = null;
this.right = null;
};
//将传入值进行判断,作为父节点的左支或右支
var insertNode = function (node, newNode) {
if (newNode.key < node.key) {
//如果传入值小于父节点,作为左支,不过要先进行判断左支是否已经存在
if (node.left === null) {
//如果左支是null空值,将传入值作为左支
node.left = newNode;
} else {
//否则(左支已经存在)继续执行函数进行下个节点的判断
insertNode(node.left, newNode);
}
} else {
//否则(传入值大于父节点)作为右支,不过要先进行判断右支是否已经存在
if (node.right === null) {
//如果右支是null空值,将传入值作为右支
node.right = newNode;
} else {
//否则(右支已经存在)继续执行函数进行下个节点的判断
insertNode(node.right, newNode);
}
}
};
//函数的入口,第一步执行的函数,确定root根的值
this.insert = function (key) {
var newNode = new Node(key);
//newNode拥有newNode.key=key,newNode.left=null,newNode.right=null
if (root === null) {
root = newNode;
//如果没有root根,将传入值作为root根
} else {
insertNode(root, newNode)
//如果已经存在根,执行insertNode函数
}
};
//将root根值和传入值(callback)赋给inOrderTraverseNod(),执行inOrderTraverseNod()
this.inOrderTraverse = function (callback) {
inOrderTraverseNode(root, callback);
};
};
//传入子节点(callback)和父节点(node)(第一次的父节点就是root)
var inOrderTraverseNode = function (node, callback) {
//如果父节点存在,继续将左支和右支执行inOrderTraverseNod(),直到不存在子分支为止
// !!注意if结构里面的函数执行顺序,先执行inOrderTraverseNode(node.left,callback);再执行callback(node.key);最后执行inOrderTraverseNode(node.right,callback);
//当inOrderTraverseNode(node.left,callback);执行完之后,才会再执行callback(node.key);(即先打印完左分支的值,再打印最顶层的父节点,这样就达到了从小到大的排序效果).右分支同理
if (node !== null) {
inOrderTraverseNode(node.left, callback);
callback(node.key);
inOrderTraverseNode(node.right, callback);
}
};
var nodes = [8, 3, 10, 1, 6, 14, 4, 7, 13];
//实例化BinaryTree
var binaryTree = new BinaryTree();
//遍历nodes数组,将每个数组的值(key)传入binary.insert(),执行insert()函数
nodes.forEach(function (key) {
binaryTree.insert(key);
});
//定义callback函数,将传入callback的值打印出来
var callback = function (key) {
console.log(key);
};
//注意此callback是参数,不是function函数,执行的是inOrderTraverse(),不是上面的callback()
binaryTree.inOrderTraverse(callback);
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>JavaScript二叉树中序算法</title>
</head>
<body>
<script>
function BinaryTree() {
//初始化root根为空值
var root = null;
//将传入值添加this.key,this.left,this.right属性
var Node = function (key) {
this.key = key;
this.left = null;
this.right = null;
};
//将传入值进行判断,作为父节点的左支或右支
var insertNode = function (node, newNode) {
if (newNode.key < node.key) {
//如果传入值小于父节点,作为左支,不过要先进行判断左支是否已经存在
if (node.left === null) {
//如果左支是null空值,将传入值作为左支
node.left = newNode;
} else {
//否则(左支已经存在)继续执行函数进行下个节点的判断
insertNode(node.left, newNode);
}
} else {
//否则(传入值大于父节点)作为右支,不过要先进行判断右支是否已经存在
if (node.right === null) {
//如果右支是null空值,将传入值作为右支
node.right = newNode;
} else {
//否则(右支已经存在)继续执行函数进行下个节点的判断
insertNode(node.right, newNode);
}
}
};
//函数的入口,第一步执行的函数,确定root根的值
this.insert = function (key) {
var newNode = new Node(key);
//newNode拥有newNode.key=key,newNode.left=null,newNode.right=null
if (root === null) {
root = newNode;
//如果没有root根,将传入值作为root根
} else {
insertNode(root, newNode)
//如果已经存在根,执行insertNode函数
}
};
//将root根值和传入值(callback)赋给inOrderTraverseNod(),执行inOrderTraverseNod()
this.inOrderTraverse=function(callback){
inOrderTraverseNode(root,callback);
};
};
//传入子节点(callback)和父节点(node)(第一次的父节点就是root)
var inOrderTraverseNode=function(node,callback){
//如果父节点存在,继续将左支和右支执行inOrderTraverseNod(),直到不存在子分支为止
// !!注意if结构里面的函数执行顺序,先执行inOrderTraverseNode(node.left,callback);再执行callback(node.key);最后执行inOrderTraverseNode(node.right,callback);
//当inOrderTraverseNode(node.left,callback);执行完之后,才会再执行callback(node.key);(即先打印完左分支的值,再打印最顶层的父节点,这样就达到了从小到大的排序效果).右分支同理
if(node!==null){
inOrderTraverseNode(node.left,callback);
callback(node.key);
inOrderTraverseNode(node.right,callback);
}
};
var nodes = [8, 3, 10, 1, 6, 14, 4, 7, 13];
//实例化BinaryTree
var binaryTree = new BinaryTree();
//遍历nodes数组,将每个数组的值(key)传入binary.insert(),执行insert()函数
nodes.forEach(function (key) {
binaryTree.insert(key);
});
//定义callback函数,将传入callback的值打印出来
var callback=function(key){
console.log(key);
};
//注意此callback是参数,不是function函数,执行的是inOrderTraverse(),不是上面的callback()
binaryTree.inOrderTraverse(callback);
</script>
</body>
</html>