自己在网上看到的相关的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);
    }
   }
   

好多知识不知道
21 声望0 粉丝

想法,每个人都有,每时每刻。想法并不会一直留在脑中,时间会遗忘一切,有必要整理一些东西,记住那时的你。思维是最美的东西,让不同时间的你,用思维对话。(起高了)