概念
简介
二叉树(Binary tree)是树形结构的一个重要类型。许多实际问题抽象出来的数据结构往往是二叉树形式,即使是一般的树也能简单地转换为二叉树,而且二叉树的存储结构及其算法都较为简单,因此二叉树显得特别重要。二叉树特点是每个结点最多只能有两棵子树,且有左右之分。 二叉树是n个有限元素的集合,该集合或者为空、或者由一个称为根(root)的元素及两个不相交的、被分别称为左子树和右子树的二叉树组成,是有序树。当集合为空时,称该二叉树为空二叉树。在二叉树中,一个元素也称作一个结点
定义
二叉树(binary tree)是指树中节点的度不大于2的有序树,它是一种最简单且最重要的树。二叉树的递归定义为:二叉树是一棵空树,或者是一棵由一个根节点和两棵互不相交的,分别称作根的左子树和右子树组成的非空树;左子树和右子树又同样都是二叉树。
leetcode传送门
思路指引:想要检测一颗二叉树是否为对称二叉树,需要先构造一颗二叉树,想要构造一棵二叉树,需要先构造一个二叉树节点.
// 二叉树的节点
class Node {
constructor(val) {
this.val = val
this.left = this.right = undefined
}
}
// 二叉树
class Tree {
constructor(data) {
// 临时存储所有节点, 方便确定父子节点关系
let nodeList = []
// 顶节点
let root
for(let i = 0; i < data.length; i++) {
let node = new Node(data[i])
nodeList.push(node)
if(i > 0) {
// 计算当前节点属于哪一层
let n = Math.floor(Math.sqrt(i+1))
// 记录当前层的起始点
let p = Math.pow(2, n) - 1
// 记录上一层的起始点
let q = Math.pow(2, n-1) - 1
// 找到当前节点的父节点, 需要找到当前层的第一个节点和上一层的第一个节点, 首先要知道当前节点在哪一层
let parent = nodeList[q + Math.floor()(i-p)/2)]
// 确定左右子节点
// 小技巧,利用找的过程中找到的第一个是左节点,第二个就是右节点的特性(利用二叉树的特性有且仅有两个子节点分别为左右节点)
if(parent.left === undefined) {
parent.left = node
}else{
parent.right = node
}
}
}
root = nodeList.shift()
// 以自然的方式清空内存,此方法数组适用, Object实用null清空
nodeList.length = 0
// 或者
// nodeList = []
return root
}
/*
* @param {root} 二叉树根节点
* @return {Boolean} 是否为对称二叉树
*/
static isSymmetry(root) {
// 空二叉树也是对称二叉树
if(!root) return true
// 递归方法
// 每一步都是一样的入参和出参, 一样的处理过程
let walk = (left, right) => {
if(!left && !right) return true
if((!left && right) || (left && !right) || (left.val !== right.val)) return false
// 继续遍历下一层是否也是镜像对称的
return walk(left.left, right.right) && walk(left.right, right.left)
}
return walk(root.left, root.right)
}
}
// 导出二叉树和节点
export default Tree
export {Node}
简单上两个jest的测试用例
import Tree from './Tree'
test('Tree:1', () => {
let root = new Tree([1, 3, 3, 5, 7, 7, 5])
expect(Tree.isSymmetry(root)).toBe(true)
})
test('Tree:2', () => {
let root = new Tree([1, 2, 2, 3, 4, 5, 6])
expect(Tree.isSymmetry(root)).toBe(false)
})
还是喜欢无分号的代码!这个题目也可以用非递归的方式也就是循环去解决,更多内容持续更新中。。。
每天进步一点,就离目标近一点!