From 06fa198f983753ff5cc0dc14f7db8102c7e65e88 Mon Sep 17 00:00:00 2001 From: mmdapl <2237221210@qq.com> Date: Tue, 11 May 2021 16:31:34 +0800 Subject: [PATCH] [5.11 update tree coding] --- README.md | 6 +-- 算法/剑指/树/GetNext.js | 52 ++++++++++++++++++++++++++ 算法/剑指/树/HasSubtree.js | 54 +++++++++++++++++++++++++++ 算法/剑指/树/reConstructBinaryTree.js | 37 ++++++++++++++++++ 4 files changed, 146 insertions(+), 3 deletions(-) create mode 100644 算法/剑指/树/GetNext.js create mode 100644 算法/剑指/树/HasSubtree.js create mode 100644 算法/剑指/树/reConstructBinaryTree.js diff --git a/README.md b/README.md index d50984c..15f1913 100644 --- a/README.md +++ b/README.md @@ -209,9 +209,9 @@ ### 树 -- 重建二叉树 -- 二叉树的下一个结点 -- 树的子结构 +- [【中等】重建二叉树](./算法/剑指/树/reConstructBinaryTree.js) +- [【中等】二叉树的下一个结点](./算法/剑指/树/GetNext.js) +- [【较难】树的子结构](./算法/剑指/树/HasSubtree.js) - 二叉树的镜像 - 对称的二叉树 - 从上往下打印二叉树 diff --git a/算法/剑指/树/GetNext.js b/算法/剑指/树/GetNext.js new file mode 100644 index 0000000..7f51650 --- /dev/null +++ b/算法/剑指/树/GetNext.js @@ -0,0 +1,52 @@ +/* + * @Description: 【中等】二叉树的下一个结点 + * @Version: Beta1.0 + * @Author: 【B站&公众号】Rong姐姐好可爱 + * @Date: 2021-05-11 15:38:02 + * @LastEditors: 【B站&公众号】Rong姐姐好可爱 + * @LastEditTime: 2021-05-11 15:40:20 + */ + +/*function TreeLinkNode(x){ + this.val = x; + this.left = null; + this.right = null; + this.next = null; +}*/ +function GetNext (pNode) { + // write code here + + // 中序遍历 ---> 左-根(pNode)-右 + // 所以这里pNode的下一个结点,要么是pNode右子树的第一个最左结点(左边的叶子结点) + // 但是如果pNode的右子树为空,则pNode的下个结点,则为第一个左子树指向pNode的祖先结点 + + if (pNode.right !== null) { + // 存在右子树,寻找右子树的最左结点 + let right_node = pNode.right; + while (right_node.left !== null) { + // 一直向左找 + right_node = right_node.left; + } + // 跳出循环的时候,right_node.left==null;即:right_node为叶子结点 + return right_node + } else { + // 右子树为空,则向上找 + while (pNode.next !== null) { + let parent_node = pNode.next; + if (parent_node.left === pNode) { + return parent_node; + } + // 父结点的左子树不是指向给定的结点的话,则继续往上寻找父结点 + pNode = pNode.next; + } + + } + + // 都找不到,则返回null + return null; + + +} +module.exports = { + GetNext: GetNext +}; diff --git a/算法/剑指/树/HasSubtree.js b/算法/剑指/树/HasSubtree.js new file mode 100644 index 0000000..4664d2e --- /dev/null +++ b/算法/剑指/树/HasSubtree.js @@ -0,0 +1,54 @@ +/* + * @Description: 【较难】树的子结构 + * @Version: Beta1.0 + * @Author: 【B站&公众号】Rong姐姐好可爱 + * @Date: 2021-05-11 16:07:54 + * @LastEditors: 【B站&公众号】Rong姐姐好可爱 + * @LastEditTime: 2021-05-11 16:08:40 + */ + +/* function TreeNode(x) { + this.val = x; + this.left = null; + this.right = null; +} */ +function HasSubtree (pRoot1, pRoot2) { + // write code here + // 空树的情况 + if (pRoot1 === null || pRoot2 === null) { + return false; + } + // 1.假设子结构从根结点开始; + const is_root = isSubTreeWithRoot(pRoot1, pRoot2); + // 2 子结构从左、右子树开始; + const in_left = HasSubtree(pRoot1.left, pRoot2); + const in_right = HasSubtree(pRoot1.right, pRoot2); + + // 三种满足一种,就是子结构了 + return is_root || in_left || in_right; +} + +// 判断root2是否为root1的子集【递归实现】 +function isSubTreeWithRoot (root1, root2) { + + // root2 自己为叶子结点,此时递归来看,就是子集 + if (root2 === null) { + return true; + } + // 递归来看,root1为空了,就是非子集 + if (root1 === null) { + return false; + } + + // 判断两者元素是否匹配 + if (root1.val !== root2.val) { + // 其中某个元素不配,递归断了 + return false; + } + // 当前结点相同,继续递归校验后续左右子树结点,两树同时向左或者向右 + return isSubTreeWithRoot(root1.left, root2.left) && isSubTreeWithRoot(root1.right, root2.right) +} + +module.exports = { + HasSubtree: HasSubtree +}; \ No newline at end of file diff --git a/算法/剑指/树/reConstructBinaryTree.js b/算法/剑指/树/reConstructBinaryTree.js new file mode 100644 index 0000000..70615fe --- /dev/null +++ b/算法/剑指/树/reConstructBinaryTree.js @@ -0,0 +1,37 @@ +/* + * @Description: 【中等】重建二叉树 + * @Version: Beta1.0 + * @Author: 【B站&公众号】Rong姐姐好可爱 + * @Date: 2021-05-11 12:57:40 + * @LastEditors: 【B站&公众号】Rong姐姐好可爱 + * @LastEditTime: 2021-05-11 12:58:33 + */ + +/* function TreeNode(x) { + this.val = x; + this.left = null; + this.right = null; +} */ +function reConstructBinaryTree (pre, vin) { + // write code here + if (pre.length === 0) { + return null; + } + // 获取根节点 ,新建二叉树结点 + const rootNode = new TreeNode(pre[0]); + + const rootIndex = vin.indexOf(pre[0]); + console.log(rootIndex, pre[0], vin.slice(0, rootIndex), vin.slice(rootIndex + 1)); + console.log(rootIndex, pre[0], pre.slice(1, rootIndex), pre.slice(rootIndex + 1)); + // 注意,找中序结点的时候,需要去除根结点,先序的时候,要 + rootNode.left = reConstructBinaryTree(pre.slice(1, rootIndex + 1), vin.slice(0, rootIndex)); + rootNode.right = reConstructBinaryTree(pre.slice(rootIndex + 1), vin.slice(rootIndex + 1)) + + // + + return rootNode; + +} +module.exports = { + reConstructBinaryTree: reConstructBinaryTree +}; \ No newline at end of file