Javascript中的特殊数据结构之树

本文深入探讨使用JavaScript实现树结构的方法,包括二叉树的最大深度、翻转二叉树及二叉搜索树的最近公共祖先等问题,通过具体LeetCode题目解析,提供递归等实用解题思路。

Javascript中的特殊数据结构之树

开始

众所周知,JS是弱类型语言,最近用JS刷些树,链表这些相关题目的时候,感觉很…..

用JS解题的答案好像不是很多,本文也是对自己的JS刷题的总结!

数据结构之树结构

树是非线性结构。相关知识点:
1. 树的遍历,存储结构

常考:树的性质,树的遍历方式,存储方式
  1. 二叉树,二叉树&&树&&森林的转换

    常考:二叉树&&树&&森林的转换,二叉排序树平均查找长度

  2. 哈夫曼树,构造和编码

参看:数据结构教程第四版 李蠢葆编 清华出版社出版

题目参看

104. 二叉树的最大深度

思路:递归左右子树,记录最终左右子树深度,比较得到最大加根节点深1即可。

var maxDepth = function(root) {
    if (!root) {
      return 0;
    }
    let count=1,leftCount=0,rightCount=0;
    if (root.left) {
      leftCount+=maxDepth(root.left);
    }
    if (root.right) {
      rightCount+=maxDepth(root.right);
    }
    return count+Math.max(leftCount,rightCount);
};

226. 翻转二叉树

思路:看到题后第一反应马上是递归,独立实现时把左,右子树为空时单独考虑时出错(例:[1,2]形式的报错),最终答案没有对左,右子树单个为空做处理了:

var invertTree = function(root) {
    if (!root||(!root.left&&!root.right)) {
      return root;
    }
    let tmp=root.left;
    root.left=invertTree(root.right);
    root.right=invertTree(tmp);
// 不知道为什么这里用解构答案会出错、
// [root.left,root.right]=[invertTree(root.right),invertTree(root.right)];
    return root;
};

LeetCode 235 二叉搜索树的最近公共祖先

个人思路:刚刚开始想先判断给定的两个节点是否在同一颗子树上,如果不在:直接返根节点。如果在,记录两个节点的深度,深度不同返深度小的节点,深度相同返上层公共父节点。

实现时问题出在深度的记录和相同深度的父节点得出。最后参看别人的实现思路,最终结果如下:

var lowestCommonAncestor = function(root, p, q) {
    while(true){
        let value =  root.val;
//判断给定的两个节点是否在同一颗子树上
        if(p.val >= value && value >= q.val || p.val <= value && value <= q.val){
            return root;
        } else if(p.val > value && q.val > value){
          //俩节点与右子树时
            root =  root.right;
        } else {
          //俩节点与左子树时
            root =  root.left;
        }
    }
};

102. 二叉树的层次遍历

个人思路:层次遍历一棵树,先用个数组对象记录[{dep:现在遍历的深度,node:当前节点}]每层情况,用一个map对象取同层所有值。最后遍历map即可。

相似解题:
107. 二叉树的层次遍历 II

与102的区别在于输出,107题目要求是从底往上遍历,实际和102一样都是层次遍历,马上就可以反应区别是在输出上而已。

//107解
var levelOrderBottom = function(root) {
    if (!root) {
      return [];
    }
    let map={};
    let arr=[{dep:0,node:root}];
    while (arr.length) {
      let tmp=arr.pop();
      let node=tmp.node;
      if (!map[tmp.dep]) {
        map[tmp.dep]=[node.val];
      }else {

      //!import  

        map[tmp.dep].unshift(node.val);
      }
      if (node.left) {
        arr.push({dep:tmp.dep+1,node:node.left})
      }
      if (node.right) {
        arr.push({dep:tmp.dep+1,node:node.right})
      }
    }
    let result=[];
    for (let i in map) {
      result.push(map[i])
    }
    //与102区别在于此
    return result.reverse();
};

更多题解

LeetCode平台部分题解参看

注:有问题可以直接issues

其它题解

skyyen999

21DaysLearningCoding

总结

题目难度均不高,每道题基本上都能得到思路,但是运用JS做的题目还是太少,有点不习惯树,链表等数据结构的实现,几乎每道题目都要花很久才能A掉。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值