From f5b897833088c54fa2685048241372ae45b57f62 Mon Sep 17 00:00:00 2001 From: krahets Date: Sun, 16 Apr 2023 16:34:52 +0800 Subject: [PATCH] Add cpp code for the backtrack algorithm. --- .../backtrack_find_constrained_paths.cpp | 75 +++++++++++++++++++ .../preorder_find_constrained_paths.cpp | 45 +++++++++++ .../preorder_find_nodes.cpp | 38 ++++++++++ .../preorder_find_paths.cpp | 45 +++++++++++ .../preorder_find_nodes.java | 2 +- 5 files changed, 204 insertions(+), 1 deletion(-) create mode 100644 codes/cpp/chapter_backtracking/backtrack_find_constrained_paths.cpp create mode 100644 codes/cpp/chapter_backtracking/preorder_find_constrained_paths.cpp create mode 100644 codes/cpp/chapter_backtracking/preorder_find_nodes.cpp create mode 100644 codes/cpp/chapter_backtracking/preorder_find_paths.cpp diff --git a/codes/cpp/chapter_backtracking/backtrack_find_constrained_paths.cpp b/codes/cpp/chapter_backtracking/backtrack_find_constrained_paths.cpp new file mode 100644 index 000000000..7e2580ca4 --- /dev/null +++ b/codes/cpp/chapter_backtracking/backtrack_find_constrained_paths.cpp @@ -0,0 +1,75 @@ +/** + * File: backtrack_find_constrained_paths.cpp + * Created Time: 2023-04-16 + * Author: Krahets (krahets@163.com) + */ + +#include "../include/include.hpp" + +/* 判断当前状态是否为解 */ +bool isSolution(vector &state) { + return !state.empty() && state.back()->val == 7; +} + +/* 记录解 */ +void recordSolution(vector &state, vector> &res) { + res.push_back(state); +} + +/* 判断在当前状态下,该选择是否合法 */ +bool isValid(vector &state, TreeNode *choice) { + return choice != nullptr && choice->val != 3; +} + +/* 更新状态 */ +void makeChoice(vector &state, TreeNode *choice) { + state.push_back(choice); +} + +/* 恢复状态 */ +void undoChoice(vector &state, TreeNode *choice) { + state.pop_back(); +} + +/* 回溯算法 */ +void backtrack(vector &state, vector &choices, vector> &res) { + // 检查是否为解 + if (isSolution(state)) { + // 记录解 + recordSolution(state, res); + return; + } + // 遍历所有选择 + for (TreeNode *choice : choices) { + // 剪枝:检查选择是否合法 + if (isValid(state, choice)) { + // 尝试:做出选择,更新状态 + makeChoice(state, choice); + vector nextChoices{choice->left, choice->right}; + backtrack(state, nextChoices, res); + // 回退:撤销选择,恢复到之前的状态 + undoChoice(state, choice); + } + } +} + +int main() { + TreeNode *root = vecToTree(vector{1, 7, 3, 4, 5, 6, 7}); + cout << "\n初始化二叉树" << endl; + printTree(root); + + // 回溯算法 + vector state; + vector choices = {root}; + vector> res; + backtrack(state, choices, res); + + cout << "\n输出所有根节点到节点 7 的路径,要求路径中不包含值为 3 的节点" << endl; + for (vector &path : res) { + vector vals; + for (TreeNode *node : path) { + vals.push_back(node->val); + } + printVector(vals); + } +} diff --git a/codes/cpp/chapter_backtracking/preorder_find_constrained_paths.cpp b/codes/cpp/chapter_backtracking/preorder_find_constrained_paths.cpp new file mode 100644 index 000000000..5067e8c8b --- /dev/null +++ b/codes/cpp/chapter_backtracking/preorder_find_constrained_paths.cpp @@ -0,0 +1,45 @@ +/** + * File: preorder_find_constrained_paths.cpp + * Created Time: 2023-04-16 + * Author: Krahets (krahets@163.com) + */ + +#include "../include/include.hpp" + +vector path; +vector> res; + +/* 前序遍历 */ +static void preOrder(TreeNode *root) { + if (root == nullptr || root->val == 3) { + return; + } + // 尝试 + path.push_back(root); + if (root->val == 7) { + // 记录解 + res.push_back(path); + } + preOrder(root->left); + preOrder(root->right); + // 回退 + path.pop_back(); +} + +int main() { + TreeNode *root = vecToTree(vector{1, 7, 3, 4, 5, 6, 7}); + cout << "\n初始化二叉树" << endl; + printTree(root); + + // 前序遍历 + preOrder(root); + + cout << "\n输出所有根节点到节点 7 的路径,要求路径中不包含值为 3 的节点" << endl; + for (vector &path : res) { + vector vals; + for (TreeNode *node : path) { + vals.push_back(node->val); + } + printVector(vals); + } +} diff --git a/codes/cpp/chapter_backtracking/preorder_find_nodes.cpp b/codes/cpp/chapter_backtracking/preorder_find_nodes.cpp new file mode 100644 index 000000000..3e70ce1b9 --- /dev/null +++ b/codes/cpp/chapter_backtracking/preorder_find_nodes.cpp @@ -0,0 +1,38 @@ +/** + * File: preorder_find_nodes.cpp + * Created Time: 2023-04-16 + * Author: Krahets (krahets@163.com) + */ + +#include "../include/include.hpp" + +vector res; + +/* 前序遍历 */ +static void preOrder(TreeNode *root) { + if (root == nullptr) { + return; + } + if (root->val == 7) { + // 记录解 + res.push_back(root); + } + preOrder(root->left); + preOrder(root->right); +} + +int main() { + TreeNode *root = vecToTree(vector{1, 7, 3, 4, 5, 6, 7}); + cout << "\n初始化二叉树" << endl; + printTree(root); + + // 前序遍历 + preOrder(root); + + cout << "\n输出所有值为 7 的节点" << endl; + vector vals; + for (TreeNode *node : res) { + vals.push_back(node->val); + } + printVector(vals); +} diff --git a/codes/cpp/chapter_backtracking/preorder_find_paths.cpp b/codes/cpp/chapter_backtracking/preorder_find_paths.cpp new file mode 100644 index 000000000..c00940d0d --- /dev/null +++ b/codes/cpp/chapter_backtracking/preorder_find_paths.cpp @@ -0,0 +1,45 @@ +/** + * File: preorder_find_paths.cpp + * Created Time: 2023-04-16 + * Author: Krahets (krahets@163.com) + */ + +#include "../include/include.hpp" + +vector path; +vector> res; + +/* 前序遍历 */ +static void preOrder(TreeNode *root) { + if (root == nullptr) { + return; + } + // 尝试 + path.push_back(root); + if (root->val == 7) { + // 记录解 + res.push_back(path); + } + preOrder(root->left); + preOrder(root->right); + // 回退 + path.pop_back(); +} + +int main() { + TreeNode *root = vecToTree(vector{1, 7, 3, 4, 5, 6, 7}); + cout << "\n初始化二叉树" << endl; + printTree(root); + + // 前序遍历 + preOrder(root); + + cout << "\n输出所有根节点到节点 7 的路径" << endl; + for (vector &path : res) { + vector vals; + for (TreeNode *node : path) { + vals.push_back(node->val); + } + printVector(vals); + } +} diff --git a/codes/java/chapter_backtracking/preorder_find_nodes.java b/codes/java/chapter_backtracking/preorder_find_nodes.java index 3208b031f..085a76593 100644 --- a/codes/java/chapter_backtracking/preorder_find_nodes.java +++ b/codes/java/chapter_backtracking/preorder_find_nodes.java @@ -32,7 +32,7 @@ public class preorder_find_nodes { res = new ArrayList<>(); preOrder(root); - System.out.println("\n输出所有根节点到节点 7 的路径"); + System.out.println("\n输出所有值为 7 的节点"); List vals = new ArrayList<>(); for (TreeNode node : res) { vals.add(node.val);