文章 评论 浏览 29
上面一段基本是在介绍树相关的概念,接下来配合概念用JS代码实现树的相关操作。
参考:
遍历二叉树(Traversing Binary Tree):是指按指定的规律对二叉树中的每个结点访问一次且仅访问一次。二叉树的遍历主要分三种:
class BinaryTree { static from(array) { const root = new BinaryTree() if (array == null || !Array.isArray(array)) { root.level = 1 root.data = array return root } preOrderTraverse(root, 0, function (node, value, level) { node.data = value node.level = level }, 1) return root function preOrderTraverse(node, index, visit, level) { visit(node, array[index], level) if (array[2 * index + 1] != null) { preOrderTraverse(node.left = new BinaryTree(), 2 * index + 1, visit, node.level + 1) } if (array[2 * index + 2] != null) { preOrderTraverse(node.right = new BinaryTree(), 2 * index + 2, visit, node.level + 1) } } } constructor(data, left, right) { this.data = data this.left = left this.right = right } toString() { return this.toLevelArray().join() } toLevelArray() { const array = [] this.preOrderTraverse((v, level) => { array[level - 1] ? array[level - 1].push(v) : (array[level - 1] = [v]) }) return array } getDepth() { let level = 0 this.preOrderTraverse((v, l) => { if (l > level) { level = l } }) return level } /** * 链式存储结构的递归先序遍历 (根左右) * * 若二叉树为空,则遍历结束;否则 * ⑴ 访问根结点; * ⑵ 先序遍历左子树(递归调用本算法); * ⑶ 先序遍历右子树(递归调用本算法)。 */ preOrderTraverse(visit) { visit(this.data, this.level, this) if (this.left) this.left.preOrderTraverse(visit) if (this.right) this.right.preOrderTraverse(visit) } /** * 链式存储结构的 **非递归** 先序遍历 */ preOrderTraverseNR(visit) { const stack = [] stack.push(this) while (stack[0]) { let p // 向左走到尽头 while ((p = stack[stack.length - 1])) { (p.data != null) && visit(p.data, p.level, p) stack.push(p.left) } // 删掉空节点 stack.pop() // 删掉根节点,进栈右节点 if (stack[0]) { p = stack.pop() stack.push(p.right) } } } /** * 递归中序遍历 (左根右) * * 若二叉树为空,则遍历结束;否则 * ⑴ 中序遍历左子树(递归调用本算法); * ⑵ 访问根结点; * ⑶ 中序遍历右子树(递归调用本算法)。 */ inOrderTraverse(visit) { if (this.left) this.left.inOrderTraverse(visit) visit(this.data, this.level, this) if (this.right) this.right.inOrderTraverse(visit) } /** * **非递归** 中序遍历 */ inOrderTraverseNR(visit) { const stack = [] stack.push(this) while (stack[0]) { let p // 向左走到尽头 while ((p = stack[stack.length - 1])) { stack.push(p.left) } // 删除空节点 stack.pop() // 删掉根节点,进栈右节点 if (stack[0]) { p = stack.pop() ;(p.data != null) && visit(p.data, p.level, p) stack.push(p.right) } } } /** * 递归后序遍历 (左右根) * * 若二叉树为空,则遍历结束;否则 * ⑴ 后序遍历左子树(递归调用本算法); * ⑵ 后序遍历右子树(递归调用本算法) ; * ⑶ 访问根结点 。 */ postOrderTraverse(visit) { if (this.left) this.left.postOrderTraverse(visit) if (this.right) this.right.postOrderTraverse(visit) visit(this.data, this.level, this) } /** * 非递归后序遍历 * * (1) 根结点入栈,且mark = 0; * (2) 若栈不为空,出栈到node; * (3) 若node的mark = 0,修改当前node的mark为1,左子树入栈; * (4) 若node的mark = 1,修改当前node的mark为2,右子树入栈; * (5) 若node的mark = 2,访问当前node结点的值; * (6) 直到栈为空结束。 */ postOrderTraverseNR(visit) { const stack = [] stack.push([this, 0]) while (stack[0]) { let p = stack.pop() let node = p[0] switch (p[1]) { case 0: stack.push([node, 1]) if (node.left) { stack.push([node.left, 0]) } break case 1: stack.push([node, 2]) if (node.right) { stack.push([node.right, 0]) } break case 2: (node.data != null) && visit(node.data, node.level, node) break default: break } } } } // const tree = BinaryTree.from([0, 1, 2, 3, 4, 5, 6, null, 8, 9]) // tree.preOrderTraverse(v => console.log(v))
@mingxing9921 大写的尴尬。。。 这篇文章都没写完
v-if: Watcher监听数据变化,然后,render函数生成VNode对象,patch方法对比新旧VNode, DOM Diff 算法修改真正的DOM元素
在vue 中 vue 做了处理如果我们自己在非vue 中需要对很多元素添加事件的时候,可以通过将事件添加到它们的父节点而将事件委托给父节点来触发处理函数
文章 0 评论 0
接受
上面一段基本是在介绍树相关的概念,接下来配合概念用JS代码实现树的相关操作。
参考:
3.6.1 二叉树与先序/中序/后序遍历
遍历二叉树(Traversing Binary Tree):是指按指定的规律对二叉树中的每个结点访问一次且仅访问一次。
二叉树的遍历主要分三种:
JavaScript 与简单算法