自己在网上看到的相关的Javascript算法,持续总结,看别人的算法总觉得很难理解。等自己想不出来的时候就会觉得容易理解了。
二叉树相关,首先是构建二叉树。
从先序遍历的结果和中序遍历的结果还原二叉树的结构,先序遍历结果{1,2,4,7,3,5,6,8},中序遍历结果{4,7,2,1,5,3,8,6},原树中无重复数字
function Node(data,left,right){
this.data = data;
this.left = left;
this.right = right;
}
function buildBinaryTree(preorder,inorder){
if(preorder.length!=inorder.length) return null;//考虑了一些特殊情况
if(preorder.length<0) return null;
if(preorder.length==1) return new Node(preorder[0],null,null);//递归结束的地方
var data = preorder[0];//根节点的值,根据先序遍历的特点。
var root = null;
var len = preorder.length;
var index;
for( index=0 ; index<len; index ++){
if(inorder[index]==data){//从中序节点中找到这个根节点的值来区分左子树和右子树
if(index==0){//考虑左子树是null
var preorderOfRight = preorder.slice(1);
var inorderOfRight = inorder.slice(1);
root = new Node(data,null,buildBinaryTree(preorderOfRight,inorderOfRight));
}
else if(index==len-1){//考虑右子树是null
var preorderOfLeft = preorder.slice(1);
var inorderOfLeft = inorder.slice(0,len-1);
root = new Node(data,buildBinaryTree(preorderOfLeft, inorderOfLeft),null);
}
else{//考虑左右子树皆有,分别构建左子树的先序遍历结果和中序遍历结果,以创建递归条件
var lenOfLeft = index;
var inorderOfLeft=inorder.slice(0,index);
var preorderOfLeft=preorder.slice(1,lenOfLeft+1);
var inorderOfRight=inorder.slice(index+1);
var preorderOfRight=preorder.slice(lenOfLeft+1);
root = new Node(data,buildBinaryTree(preorderOfLeft, inorderOfLeft), buildBinaryTree(preorderOfRight, inorderOfRight));
}
break;
}
}
return root;
}
其次是利用非递归算法来获得二叉树的遍历结果。关键就是用stack来保存树的访问结构。通过pop,push保存访问的顺序,通过node的type来决定是继续分解还是直接输出结果。
function preOrder(root){ //
if(!root||!root.data) return [];//只是为了区分特殊情况。
var nodeLeft = []; //储存要遍历的节点
nodeLeft.push(root);
while(nodeLeft.length>0){
var node = nodeLeft.pop();
console.log(node.data); //先序的话,没必要区分储存的数据是object还是number,因为直接输出就好了。
if(node.right&&node.right instanceof Node) nodeLeft.push(node.right); //如果有右节点,那么先存起来,因为要先分析左节点。
if(node.left&&node.left instanceof Node) nodeLeft.push(node.left);
}
}
function inOrder(root){
if(!root||!root.data) return [];
var nodeLeft = [];
nodeLeft.push(root);
while(nodeLeft.length>0){
var node = nodeLeft.pop();
if(typeof node =="number"){ //data type is number
console.log(node);
continue;
}
if(node.right&&node.right instanceof Node) nodeLeft.push(node.right); //我觉得对于node的检测应该在node创建的时候完成。
nodeLeft.push(node.data); //按照遍历顺序存储
if(node.left&&node.left instanceof Node) nodeLeft.push(node.left);
}
}
function postOrder(root){
if(!root||!root.data) return [];
var nodeLeft = [];
nodeLeft.push(root);
while(nodeLeft.length>0){
var node = nodeLeft.pop();
if(typeof node ==="number"){
console.log(node);
continue;
}
nodeLeft.push(node.data);
if(node.right&&node.right instanceof Node) nodeLeft.push(node.right);//I think the check for whether this is a qualified node should be done when the node is built.
if(node.left&&node.left instanceof Node) nodeLeft.push(node.left);
}
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。