<script type="text/javascript"> //javascript实现属性结构 //相当于用于创建结点 (function(window){ function Btree(str){ this.leftheight = null; this.rightheight = null; this.leftCountNode = null; this.rightCountNode = null; this.ChildNode = null; //保存树的高度 this.height = null; //保存树的结点 this.countNode = null; this.struct = null; //构建树 this.createTree(str); //获取输的信息 this.init(this.struct); }; Btree.prototype = { BtreeNode:function(){ this.left = null; this.right = null; this.data = null; }, createTree:function(str){ var Btree = null;//一个空二叉树 var arr = [];//用一个数组表示栈 var top = 1;//指向栈底 var p = null; var k; Btree = p; var index = 0;//字符串的索引 while(index<str.length){ switch(str[index]){ case '(':arr.push(p),k=1;break; case ',':k=2;break; case ')':arr.pop();break; default: p = new this.BtreeNode(); p.data = str[index]; if(Btree == null){ Btree=p; }else{ switch(k){ case 1:arr[arr.length-1].left = p;break; case 2:arr[arr.length-1].right = p;break; } } ; } index++; } this.struct = Btree; }, init:function(node){ this.getheight(node); this.ChildNode = this.getCountNode(node); }, getheight:function(node){ if(node == null){ return 0; }else{ this.leftheight = this.getheight(node.left); this.rightheight = this.getheight(node.right);
return this.height = this.leftheight>this.rightheight?this.leftheight+1:this.rightheight+1;
//修改如下 上面的代码有个问题就是每一层的高度都被后面的个覆盖掉了因为使用的是对象的某个属性因此一直被改变二无法保留当前层的数值
var leftheight = this.getheight(node.left); var rightheight = this.getheight(node.right);
return this.height = leftheight>rightheight?leftheight+1:rightheight+1;
} },//结点个数 getCountNode:function(node){ var left,right; if(node == null){ return 0; }else if(node.left == null && node.right == null){ return 1; }else{ left = this.getCountNode(node.left); right = this.getCountNode(node.right); return (left+right); //注意这里的left不应该使用this.left 或者this.right 这样在递归过程当中会被覆盖掉 } },//显示二叉树 TreeShow:function(Btree,height=0){ //思路先判断该对象是否有左孩子或者右孩子 如果有就递归输出 if(Btree != null){ //首先将当前结点的值输出 Btree.data = Btree.data; var str = ""; for(var i=0;i<height;i++){ str+="--"; } console.log(str + Btree.data); //判断是否还有子节点如果有则继续递归输出 if(Btree.left != null || Btree.right != null){ this.TreeShow(Btree.left,++height); this.TreeShow(Btree.right,height); } } }, TreeAll:function(Btree,height = 0){ //思路先判断该对象是否有左孩子或者右孩子 如果有就递归输出 if(Btree != null){ //首先将当前结点的值输出 Btree.data = Btree.data; var str = ""; for(var i=0;i<height;i++){ str+="--"; } //判断是否还有子节点如果有则继续递归输出 if(Btree.left != null || Btree.right != null){ this.TreeShow(Btree.left,++height); console.log(str + Btree.data); this.TreeShow(Btree.right,height); } } } } window.Btree = Btree; })(window) var str = "1(2(9,3(7,0)),4(6(1,3),8(1,2)))"; var t = new Btree(str); t.TreeShow(t.struct,0); console.log("============="); t.TreeAll(t.struct); </script> </html>
结果
根据二叉树创建顺序表
//根据二叉树创建顺序表 //注意这里应该从第一个结点开始 createArr:function(tree,i=1){ //如果当前的二叉树为空树 if(tree != null){ this.structArr[i] = tree.data; console.log(tree.data); /* 解析这里可以看成嵌套多层函数 每次都 先处理上一层再处理下一层 但在这里因为每层的i不变所以下面的函数调用顺序可以改变 */ this.createArr(tree.left,2*i);//找左结点 this.createArr(tree.right,2*i+1);//找右结点 } //如果为空着保存# else{ //这个是当结点为null的时候保存为# 这个结点也就停止递归了因此会有一段空间是没有存储到数据的 或者但整个顺序表占用的数据还是很多的 //所以比较适合存储满树 this.structArr[i] = "#"; }
根据顺序表创建二叉树也差不多
每次递归某个数的时候都将这个结点的值在数组当中的位置一起传过去只要这个位置的数组值不等于#就说明则是一个结点然后赋值并且将孩子结点再次递归遍历
获取每个叶子结点的路径
再次修改。。。这次没问题了
getPath:function(tree,i=1){ //这里可能会因为某个结点的某个孩子结点不存在 if(tree!=null){ (this.path)[i]="-"+tree.data; //判断该节点是否为叶子结点 //因为这里只是筛选出叶子结点可能出现结点只有一个孩子的情况 在下面都会做一次递归因此外边应该去除不存在的情况 if(tree.left == null&&tree.right == null){ var str = ""; for(var j=1;j<=i;j++){ str+=(this.path)[j]; } console.log(str); }else{ i++; this.getPath(tree.left,i); this.getPath(tree.right,i); } } }
var str = "1(2(9,3(7,0)),4(6(1(2,3(5,1)),3),8(1,2)))"; 用于创建二叉树的括号表达式