From 01345c23ca10d51513c02962a95a91250b396e2e Mon Sep 17 00:00:00 2001 From: Justin Tse Date: Thu, 11 May 2023 23:46:12 +0800 Subject: [PATCH] Add JavaScript and TypeScript code of preorder traversal (Chapter of Backtracking) (#490) * Add JavaScript and TypeScript code of preorder traversal (Chapter of Backtracking) * Update preorder_traversal_iii_compact.ts --- .../preorder_traversal_i_compact.js | 33 +++++++++ .../preorder_traversal_ii_compact.js | 40 +++++++++++ .../preorder_traversal_iii_compact.js | 41 +++++++++++ .../preorder_traversal_iii_template.js | 69 ++++++++++++++++++ .../preorder_traversal_i_compact.ts | 34 +++++++++ .../preorder_traversal_ii_compact.ts | 41 +++++++++++ .../preorder_traversal_iii_compact.ts | 42 +++++++++++ .../preorder_traversal_iii_template.ts | 70 +++++++++++++++++++ 8 files changed, 370 insertions(+) create mode 100644 codes/javascript/chapter_backtracking/preorder_traversal_i_compact.js create mode 100644 codes/javascript/chapter_backtracking/preorder_traversal_ii_compact.js create mode 100644 codes/javascript/chapter_backtracking/preorder_traversal_iii_compact.js create mode 100644 codes/javascript/chapter_backtracking/preorder_traversal_iii_template.js create mode 100644 codes/typescript/chapter_backtracking/preorder_traversal_i_compact.ts create mode 100644 codes/typescript/chapter_backtracking/preorder_traversal_ii_compact.ts create mode 100644 codes/typescript/chapter_backtracking/preorder_traversal_iii_compact.ts create mode 100644 codes/typescript/chapter_backtracking/preorder_traversal_iii_template.ts diff --git a/codes/javascript/chapter_backtracking/preorder_traversal_i_compact.js b/codes/javascript/chapter_backtracking/preorder_traversal_i_compact.js new file mode 100644 index 000000000..46f8c77ce --- /dev/null +++ b/codes/javascript/chapter_backtracking/preorder_traversal_i_compact.js @@ -0,0 +1,33 @@ +/** + * File: preorder_traversal_i_compact.js + * Created Time: 2023-05-09 + * Author: Justin (xiefahit@gmail.com) + */ + +const { arrToTree } = require('../modules/TreeNode'); +const { printTree } = require('../modules/PrintUtil'); + +/* 前序遍历:例题一 */ +function preOrder(root, res) { + if (root === null) { + return; + } + if (root.val === 7) { + // 记录解 + res.push(root); + } + preOrder(root.left, res); + preOrder(root.right, res); +} + +// Driver Code +const root = arrToTree([1, 7, 3, 4, 5, 6, 7]); +console.log("\n初始化二叉树"); +printTree(root); + +// 前序遍历 +const res = []; +preOrder(root, res); + +console.log("\n输出所有值为 7 的节点"); +console.log(res.map(node => node.val)); diff --git a/codes/javascript/chapter_backtracking/preorder_traversal_ii_compact.js b/codes/javascript/chapter_backtracking/preorder_traversal_ii_compact.js new file mode 100644 index 000000000..158cd5684 --- /dev/null +++ b/codes/javascript/chapter_backtracking/preorder_traversal_ii_compact.js @@ -0,0 +1,40 @@ +/** + * File: preorder_traversal_ii_compact.js + * Created Time: 2023-05-09 + * Author: Justin (xiefahit@gmail.com) + */ + +const { arrToTree } = require('../modules/TreeNode'); +const { printTree } = require('../modules/PrintUtil'); + +/* 前序遍历:例题二 */ +function preOrder(root, path, res) { + if (root === null) { + return; + } + // 尝试 + path.push(root); + if (root.val === 7) { + // 记录解 + res.push([...path]); + } + preOrder(root.left, path, res); + preOrder(root.right, path, res); + // 回退 + path.pop(); +} + +// Driver Code +const root = arrToTree([1, 7, 3, 4, 5, 6, 7]); +console.log("\n初始化二叉树"); +printTree(root); + +// 前序遍历 +const path = []; +const res = []; +preOrder(root, path, res); + +console.log("\n输出所有根节点到节点 7 的路径"); +res.forEach(path => { + console.log(path.map(node => node.val)); +}); diff --git a/codes/javascript/chapter_backtracking/preorder_traversal_iii_compact.js b/codes/javascript/chapter_backtracking/preorder_traversal_iii_compact.js new file mode 100644 index 000000000..7e0921776 --- /dev/null +++ b/codes/javascript/chapter_backtracking/preorder_traversal_iii_compact.js @@ -0,0 +1,41 @@ +/** + * File: preorder_traversal_iii_compact.js + * Created Time: 2023-05-09 + * Author: Justin (xiefahit@gmail.com) + */ + +const { arrToTree } = require('../modules/TreeNode'); +const { printTree } = require('../modules/PrintUtil'); + +/* 前序遍历:例题三 */ +function preOrder(root, path, res) { + // 剪枝 + if (root === null || root.val === 3) { + return; + } + // 尝试 + path.push(root); + if (root.val === 7) { + // 记录解 + res.push([...path]); + } + preOrder(root.left, path, res); + preOrder(root.right, path, res); + // 回退 + path.pop(); +} + +// Driver Code +const root = arrToTree([1, 7, 3, 4, 5, 6, 7]); +console.log("\n初始化二叉树"); +printTree(root); + +// 前序遍历 +const path = []; +const res = []; +preOrder(root, path, res); + +console.log("\n输出所有根节点到节点 7 的路径,且路径中不包含值为 3 的节点"); +res.forEach(path => { + console.log(path.map(node => node.val)); +}); diff --git a/codes/javascript/chapter_backtracking/preorder_traversal_iii_template.js b/codes/javascript/chapter_backtracking/preorder_traversal_iii_template.js new file mode 100644 index 000000000..1f1ef499b --- /dev/null +++ b/codes/javascript/chapter_backtracking/preorder_traversal_iii_template.js @@ -0,0 +1,69 @@ +/** + * File: preorder_traversal_iii_template.js + * Created Time: 2023-05-09 + * Author: Justin (xiefahit@gmail.com) + */ + +const { arrToTree } = require('../modules/TreeNode'); +const { printTree } = require('../modules/PrintUtil'); + +/* 判断当前状态是否为解 */ +function isSolution(state) { + return state && state[state.length - 1]?.val === 7; +} + +/* 记录解 */ +function recordSolution(state, res) { + res.push([...state]); +} + +/* 判断在当前状态下,该选择是否合法 */ +function isValid(state, choice) { + return choice !== null && choice.val !== 3; +} + +/* 更新状态 */ +function makeChoice(state, choice) { + state.push(choice); +} + +/* 恢复状态 */ +function undoChoice(state) { + state.pop(); +} + +/* 回溯算法:例题三 */ +function backtrack(state, choices, res) { + // 检查是否为解 + if (isSolution(state)) { + // 记录解 + recordSolution(state, res); + return; + } + // 遍历所有选择 + for (const choice of choices) { + // 剪枝:检查选择是否合法 + if (isValid(state, choice)) { + // 尝试:做出选择,更新状态 + makeChoice(state, choice); + // 进行下一轮选择 + backtrack(state, [choice.left, choice.right], res); + // 回退:撤销选择,恢复到之前的状态 + undoChoice(state); + } + } +} + +// Driver Code +const root = arrToTree([1, 7, 3, 4, 5, 6, 7]); +console.log("\n初始化二叉树"); +printTree(root); + +// 回溯算法 +const res = []; +backtrack([], [root], res); + +console.log("\n输出所有根节点到节点 7 的路径,要求路径中不包含值为 3 的节点"); +res.forEach(path => { + console.log(path.map(node => node.val)); +}); diff --git a/codes/typescript/chapter_backtracking/preorder_traversal_i_compact.ts b/codes/typescript/chapter_backtracking/preorder_traversal_i_compact.ts new file mode 100644 index 000000000..6a57a105e --- /dev/null +++ b/codes/typescript/chapter_backtracking/preorder_traversal_i_compact.ts @@ -0,0 +1,34 @@ +/** + * File: preorder_traversal_i_compact.ts + * Created Time: 2023-05-09 + * Author: Justin (xiefahit@gmail.com) + */ + +import { type TreeNode } from '../modules/TreeNode'; +import { arrToTree } from '../modules/TreeNode'; +import { printTree } from '../modules/PrintUtil'; + +/* 前序遍历:例题一 */ +function preOrder(root: TreeNode | null, res: TreeNode[]): void { + if (root === null) { + return; + } + if (root.val === 7) { + // 记录解 + res.push(root); + } + preOrder(root.left, res); + preOrder(root.right, res); +} + +// Driver Code +const root = arrToTree([1, 7, 3, 4, 5, 6, 7]); +console.log("\n初始化二叉树"); +printTree(root); + +// 前序遍历 +const res: TreeNode[] = []; +preOrder(root, res); + +console.log("\n输出所有值为 7 的节点"); +console.log(res.map(node => node.val)); diff --git a/codes/typescript/chapter_backtracking/preorder_traversal_ii_compact.ts b/codes/typescript/chapter_backtracking/preorder_traversal_ii_compact.ts new file mode 100644 index 000000000..a3ce0ac87 --- /dev/null +++ b/codes/typescript/chapter_backtracking/preorder_traversal_ii_compact.ts @@ -0,0 +1,41 @@ +/** + * File: preorder_traversal_ii_compact.ts + * Created Time: 2023-05-09 + * Author: Justin (xiefahit@gmail.com) + */ + +import { type TreeNode } from '../modules/TreeNode'; +import { arrToTree } from '../modules/TreeNode'; +import { printTree } from '../modules/PrintUtil'; + +/* 前序遍历:例题二 */ +function preOrder(root: TreeNode | null, path: TreeNode[], res: TreeNode[][]): void { + if (root === null) { + return; + } + // 尝试 + path.push(root); + if (root.val === 7) { + // 记录解 + res.push([...path]); + } + preOrder(root.left, path, res); + preOrder(root.right, path, res); + // 回退 + path.pop(); +} + +// Driver Code +const root = arrToTree([1, 7, 3, 4, 5, 6, 7]); +console.log("\n初始化二叉树"); +printTree(root); + +// 前序遍历 +const path: TreeNode[] = []; +const res: TreeNode[][] = []; +preOrder(root, path, res); + +console.log("\n输出所有根节点到节点 7 的路径"); +res.forEach(path => { + console.log(path.map(node => node.val)); +}); diff --git a/codes/typescript/chapter_backtracking/preorder_traversal_iii_compact.ts b/codes/typescript/chapter_backtracking/preorder_traversal_iii_compact.ts new file mode 100644 index 000000000..97eacf4d6 --- /dev/null +++ b/codes/typescript/chapter_backtracking/preorder_traversal_iii_compact.ts @@ -0,0 +1,42 @@ +/** + * File: preorder_traversal_iii_compact.ts + * Created Time: 2023-05-09 + * Author: Justin (xiefahit@gmail.com) + */ + +import { type TreeNode } from '../modules/TreeNode'; +import { arrToTree } from '../modules/TreeNode'; +import { printTree } from '../modules/PrintUtil'; + +/* 前序遍历:例题三 */ +function preOrder(root: TreeNode | null, path: TreeNode[], res: TreeNode[][]): void { + // 剪枝 + if (root === null || root.val === 3) { + return; + } + // 尝试 + path.push(root); + if (root.val === 7) { + // 记录解 + res.push([...path]); + } + preOrder(root.left, path, res); + preOrder(root.right, path, res); + // 回退 + path.pop(); +} + +// Driver Code +const root = arrToTree([1, 7, 3, 4, 5, 6, 7]); +console.log("\n初始化二叉树"); +printTree(root); + +// 前序遍历 +const path: TreeNode[] = []; +const res: TreeNode[][] = []; +preOrder(root, path, res); + +console.log("\n输出所有根节点到节点 7 的路径,且路径中不包含值为 3 的节点"); +res.forEach(path => { + console.log(path.map(node => node.val)); +}); diff --git a/codes/typescript/chapter_backtracking/preorder_traversal_iii_template.ts b/codes/typescript/chapter_backtracking/preorder_traversal_iii_template.ts new file mode 100644 index 000000000..2dab6850a --- /dev/null +++ b/codes/typescript/chapter_backtracking/preorder_traversal_iii_template.ts @@ -0,0 +1,70 @@ +/** + * File: preorder_traversal_iii_template.ts + * Created Time: 2023-05-09 + * Author: Justin (xiefahit@gmail.com) + */ + +import { type TreeNode } from '../modules/TreeNode'; +import { arrToTree } from '../modules/TreeNode'; +import { printTree } from '../modules/PrintUtil'; + +/* 判断当前状态是否为解 */ +function isSolution(state: TreeNode[]): boolean { + return state && state[state.length - 1]?.val === 7; +} + +/* 记录解 */ +function recordSolution(state: TreeNode[], res: TreeNode[][]): void { + res.push([...state]); +} + +/* 判断在当前状态下,该选择是否合法 */ +function isValid(state: TreeNode[], choice: TreeNode): boolean { + return choice !== null && choice.val !== 3; +} + +/* 更新状态 */ +function makeChoice(state: TreeNode[], choice: TreeNode): void { + state.push(choice); +} + +/* 恢复状态 */ +function undoChoice(state: TreeNode[]): void { + state.pop(); +} + +/* 回溯算法:例题三 */ +function backtrack(state: TreeNode[], choices: TreeNode[], res: TreeNode[][]): void { + // 检查是否为解 + if (isSolution(state)) { + // 记录解 + recordSolution(state, res); + return; + } + // 遍历所有选择 + for (const choice of choices) { + // 剪枝:检查选择是否合法 + if (isValid(state, choice)) { + // 尝试:做出选择,更新状态 + makeChoice(state, choice); + // 进行下一轮选择 + backtrack(state, [choice.left, choice.right], res); + // 回退:撤销选择,恢复到之前的状态 + undoChoice(state); + } + } +} + +// Driver Code +const root = arrToTree([1, 7, 3, 4, 5, 6, 7]); +console.log("\n初始化二叉树"); +printTree(root); + +// 回溯算法 +const res: TreeNode[][] = []; +backtrack([], [root], res); + +console.log("\n输出所有根节点到节点 7 的路径,要求路径中不包含值为 3 的节点"); +res.forEach(path => { + console.log(path.map(node => node.val)); +});