二叉树与对称二叉树

92 阅读3分钟

概念

简介

二叉树(Binary tree)是树形结构的一个重要类型。许多实际问题抽象出来的数据结构往往是二叉树形式,即使是一般的树也能简单地转换为二叉树,而且二叉树的存储结构及其算法都较为简单,因此二叉树显得特别重要。二叉树特点是每个结点最多只能有两棵子树,且有左右之分。 二叉树是n个有限元素的集合,该集合或者为空、或者由一个称为根(root)的元素及两个不相交的、被分别称为左子树和右子树的二叉树组成,是有序树。当集合为空时,称该二叉树为空二叉树。在二叉树中,一个元素也称作一个结点

定义

二叉树(binary tree)是指树中节点的度不大于2的有序树,它是一种最简单且最重要的树。二叉树的递归定义为:二叉树是一棵空树,或者是一棵由一个根节点和两棵互不相交的,分别称作根的左子树和右子树组成的非空树;左子树和右子树又同样都是二叉树。

leetcode传送门

leetcode-cn.com/problems/sy…

思路指引:想要检测一颗二叉树是否为对称二叉树,需要先构造一颗二叉树,想要构造一棵二叉树,需要先构造一个二叉树节点.

// 二叉树的节点
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)
})

还是喜欢无分号的代码!这个题目也可以用非递归的方式也就是循环去解决,更多内容持续更新中。。。

每天进步一点,就离目标近一点!