今天在用javasceript进行二叉树的编程时,自己写的代码总是无法生成二叉树,根结点总是显示null。对比了一下代码,原来是值传递和引用传递的问题。话不多说,直接放代码。
//节点类
class Node {
constructor(key) {
this.left = null
this.right = null
this.key = key
}
}
//二叉树类
class BinaryTree {
constructor() {
this.root = null
}
insert (key) {
const newNode = new Node(key)
if (this.root === null) {
this.root = newNode
} else {
this.inOrderTraversNode(this.root, newNode)
}
}
inOrderTraversNode (node, newNode) {
if (newNode.key < node.key) { // 左插
if (node.left === null) {
node.left = newNode
}else{
this.inOrderTraversNode(node.left, newNode)
}
} else { // 右插
if (node.right === null) {
node.right = newNode
} else {
this.inOrderTraversNode(node.right, newNode)
}
}
}
}
//用于测试代码
const node = [8, 1, 3, 10, 12, 6, 13, 15, 18, 7]
const binaryTree = new BinaryTree()
node.map(function(item) {
binaryTree.insert(item)
})
console.log(binaryTree.root)
以上是可完成二叉树生成的正常代码,可以发现这段代码的BinaryTree类里面,insert和 inOrderTraversNode都有node是否为空的判断,似乎有点多余,so作者灵光一闪,产生了下面的代码:
//节点类
class Node {
constructor (key) {
this.left=null;
this.right=null;
this.key=key;
}
}
//二叉树类
class BinaryTree {
constructor () {
this.root=null
}
insertNode (newNode) {
console.log('root: ',this.root)
this.insertNewNode(this.root,newNode)
}
insertNewNode (preNode,newNode) {
console.log('root: ',preNode)
if (preNode===null) {
preNode=newNode; console.log('1',preNode,newNode)
} else {
let preKey=preNode.key,
newKey=newNode.key;console.log('2')
if (newKey<preKey) {
this.insertNewNode(preNode.left,newNode);console.log('3')
} else this.insertNewNode(preNode.right,newNode);
}
}
}
//测试代码
const arr=[4,6,3,1,8,9];
let binaryTree=new BinaryTree();
for (let a of arr) {
binaryTree.insertNode(new Node(a));
}
console.log(binaryTree.root);
结果,大失所望,root一直输出null。仔细对比代码,发现:正常代码,insertNode函数函数中,传入的一直都是引用值,其实我的代码中传入的也是引用值,差别是他在函数中运用obj.key来赋值,而我直接用obj来赋值,所以出现了乌龙。
这里有段测试代码,结合上面加粗的总结看看控制台会打印出什么。
let root={'left':null,
'right':null,
'key':1};
let obj={'left':null,
'right':null,
'key':2}
function test(pra,newNode) {
pra=newNode;
}
test(root.left,obj);
console.log(root);
function testOther(pra,newNode) {
pra.left=newNode;
}
testOther(root,obj);
console.log(root);
最后有个彩蛋,js中函数参数的传递方式不管是值传递还是引用传递,其实,归根结底,都是值传递,只是引用传递的是对象存储地址的值。