forked from krahets/hello-algo
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: Add C codes for the chapter backtracking (krahets#593)
* fix(codes/cpp): Memory leak fix: the space was not freed when pop removed the element. * fix(codes/cpp): Fix access error when printArray(arr, 0) * Update PrintUtil.hpp * fix(codes/c): Fix some errors of cmake build * feat(codes/c): Add hashing_search.c * styles(codes/c): Modify function description * styles(codes/c): Modify binary_search.c code style * fix(codes/c): Fix the problem in binary_tree_bfs.c and the problem that the memory is not released. * feat: Add preorder_traversal_i_compact.c * feat(codes/c): Add head_sort.c * feat(codes/c): Add bucket_sort.c * feat(codes/c): Add binary_search_edge.c * fix(codes/c): Add programs that are not managed by cmake (c code) * feat(codes/c): Add selection_sort.c * style(codes/c): Change swap in selection_sort.c to `selectionSort` * styles(codes/c): Change style. * fix(codes/c): Fix some formatting errors and temporarily remove backtracking chapters * feat(codes/c): Add part of the c code in the backtracking chapter * feat(codes/c): Add preorder_traversal_iii_compact.c * feat(codes/c): Add preorder_traversal_iii_template.c * feat(codes/c): Add permutations_i.c * style(codes/c): Adjust the format * feat(codes/c): Add memory release in chapter_backtracking * fix(codes/c): Fix memory release issue. * style(codes/c): Update format and Merge duplicate code * style(code/c): Change print format in preorder_traversal_iii_template.c * Update preorder_traversal_iii_template.c * Update permutations_i.c * feat(codes/c): Remove myArray, use public vector. * feat(codes/c): Add subset_sum_i_naive.c in C codes. * feat(codes/c): Add permutations_i in CMakeLists.txt * feat(codes/c): Update printf function in vector.h. * feat(codes/c): Add subset_sum_i.c and subset_sum_ii.c --------- Co-authored-by: Yudong Jin <[email protected]>
- Loading branch information
Showing
12 changed files
with
741 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
add_executable(permutations_i permutations_i.c) | ||
add_executable(preorder_traversal_i_compact preorder_traversal_i_compact.c) | ||
add_executable(preorder_traversal_ii_compact preorder_traversal_ii_compact.c) | ||
add_executable(preorder_traversal_iii_compact preorder_traversal_iii_compact.c) | ||
add_executable(preorder_traversal_iii_template preorder_traversal_iii_template.c) | ||
add_executable(subset_sum_i_naive subset_sum_i_naive.c) | ||
add_executable(subset_sum_i subset_sum_i.c) | ||
add_executable(subset_sum_ii subset_sum_ii.c) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
/** | ||
* File: permutations_i.c | ||
* Created Time: 2023-06-04 | ||
* Author: Gonglja ([email protected]) | ||
*/ | ||
|
||
#include "../utils/common.h" | ||
|
||
/* 回溯算法:全排列 I */ | ||
void backtrack(vector *state, vector *choices, vector *selected, vector *res) { | ||
// 当状态长度等于元素数量时,记录解 | ||
if (state->size == choices->size) { | ||
vector *newState = newVector(); | ||
for (int i = 0; i < state->size; i++) { | ||
vectorPushback(newState, state->data[i]); | ||
} | ||
vectorPushback(res, newState); | ||
return; | ||
} | ||
// 遍历所有选择 | ||
for (int i = 0; i < choices->size; i++) { | ||
int *choice = malloc(sizeof(int)); | ||
*choice = *((int *)(choices->data[i])); | ||
// 剪枝:不允许重复选择元素 且 不允许重复选择相等元素 | ||
bool select = *((bool *)(selected->data[i])); | ||
if (!select) { | ||
// 尝试:做出选择,更新状态 | ||
*((bool *)selected->data[i]) = true; | ||
vectorPushback(state, choice); | ||
// 进行下一轮选择 | ||
backtrack(state, choices, selected, res); | ||
// 回退:撤销选择,恢复到之前的状态 | ||
*((bool *)selected->data[i]) = false; | ||
vectorPopback(state); | ||
} | ||
} | ||
} | ||
|
||
/* 全排列 I */ | ||
vector *permutationsI(vector *nums) { | ||
vector *iState = newVector(); | ||
|
||
int select[3] = {false, false, false}; | ||
vector *bSelected = newVector(); | ||
for (int i = 0; i < nums->size; i++) { | ||
vectorPushback(bSelected, &select[i]); | ||
} | ||
|
||
vector *res = newVector(); | ||
|
||
// 前序遍历 | ||
backtrack(iState, nums, bSelected, res); | ||
return res; | ||
} | ||
|
||
/* 打印向量中的元素 */ | ||
void printFunc(vector *v, void *p) { | ||
TreeNode *node = p; | ||
printf("%d", node->val); | ||
} | ||
|
||
/* Driver Code */ | ||
int main() { | ||
int nums[] = {1, 2, 3}; | ||
vector *iNums = newVector(); // int | ||
for (int i = 0; i < sizeof(nums) / sizeof(nums[0]); i++) { | ||
vectorPushback(iNums, &nums[i]); | ||
} | ||
|
||
vector *res = permutationsI(iNums); | ||
|
||
// 输出结果 | ||
printf("输入数组 nums = "); | ||
printArray(nums, sizeof(nums) / sizeof(nums[0])); | ||
printf("所有排列 res = "); | ||
printVectorMatrix(res, printFunc); | ||
|
||
// 释放内存 | ||
delVector(res); | ||
return 0; | ||
} |
44 changes: 44 additions & 0 deletions
44
codes/c/chapter_backtracking/preorder_traversal_i_compact.c
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
/** | ||
* File: preorder_traversal_i_compact.c | ||
* Created Time: 2023-05-10 | ||
* Author: Gonglja ([email protected]) | ||
*/ | ||
|
||
#include "../utils/common.h" | ||
|
||
vector *res; | ||
|
||
// 打印向量中的元素 | ||
void printFunc(vector *v, void *p) { | ||
TreeNode *node = p; | ||
printf("%d ", node->val); | ||
} | ||
|
||
/* 前序遍历:例题一 */ | ||
static void preOrder(TreeNode *root) { | ||
if (root == NULL) { | ||
return; | ||
} | ||
if (root->val == 7) { | ||
// 记录解 | ||
vectorPushback(res, root); | ||
} | ||
preOrder(root->left); | ||
preOrder(root->right); | ||
} | ||
|
||
/* Driver Code */ | ||
int main() { | ||
int arr[] = {1, 7, 3, 4, 5, 6, 7}; | ||
res = newVector(); | ||
TreeNode *root = arrToTree(arr, sizeof(arr) / sizeof(arr[0])); | ||
printf("\n初始化二叉树\r\n"); | ||
printTree(root); | ||
|
||
// 前序遍历 | ||
preOrder(root); | ||
|
||
printf("\n输出所有值为 7 的节点\r\n"); | ||
printVector(res, printFunc); | ||
delVector(res); | ||
} |
67 changes: 67 additions & 0 deletions
67
codes/c/chapter_backtracking/preorder_traversal_ii_compact.c
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
/** | ||
* File: preorder_traversal_ii_compact.c | ||
* Created Time: 2023-05-28 | ||
* Author: Gonglja ([email protected]) | ||
*/ | ||
|
||
#include "../utils/common.h" | ||
|
||
/* 前序遍历:例题二 */ | ||
void preOrder(TreeNode *root, vector *path, vector *res) { | ||
if (root == NULL) { | ||
return; | ||
} | ||
// 尝试 | ||
vectorPushback(path, root); | ||
if (root->val == 7) { | ||
// 记录解 | ||
vector *newPath = newVector(); | ||
for (int i = 0; i < path->size; i++) { | ||
vectorPushback(newPath, path->data[i]); | ||
} | ||
vectorPushback(res, newPath); | ||
} | ||
|
||
preOrder(root->left, path, res); | ||
preOrder(root->right, path, res); | ||
|
||
// 回退 | ||
vectorPopback(path); | ||
} | ||
|
||
// 打印向量中的元素 | ||
void printResult(vector *vv) { | ||
for (int i = 0; i < vv->size; i++) { | ||
vector *v = (vector *)vv->data[i]; | ||
for (int j = 0; j < v->size; j++) { | ||
TreeNode *node = (TreeNode *)v->data[j]; | ||
printf("%d ", node->val); | ||
} | ||
printf("\n"); | ||
} | ||
} | ||
|
||
/* Driver Code */ | ||
int main() { | ||
int arr[] = {1, 7, 3, 4, 5, 6, 7}; | ||
int n = sizeof(arr) / sizeof(arr[0]); | ||
TreeNode *root = arrToTree(arr, n); | ||
printf("\r\n初始化二叉树\r\n"); | ||
printTree(root); | ||
|
||
// 创建存储路径和结果的向量 | ||
vector *path = newVector(); | ||
vector *res = newVector(); | ||
|
||
// 前序遍历 | ||
preOrder(root, path, res); | ||
|
||
// 输出结果 | ||
printf("输出所有根节点到节点 7 的路径:\n"); | ||
printResult(res); | ||
|
||
// 释放内存 | ||
delVector(path); | ||
delVector(res); | ||
return 0; | ||
} |
69 changes: 69 additions & 0 deletions
69
codes/c/chapter_backtracking/preorder_traversal_iii_compact.c
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
/** | ||
* File: preorder_traversal_iii_compact.c | ||
* Created Time: 2023-06-04 | ||
* Author: Gonglja ([email protected]) | ||
*/ | ||
|
||
#include "../utils/common.h" | ||
|
||
/* 前序遍历:例题三 */ | ||
void preOrder(TreeNode *root, vector *path, vector *res) { | ||
// 剪枝 | ||
if (root == NULL || root->val == 3) { | ||
return; | ||
} | ||
// 尝试 | ||
vectorPushback(path, root); | ||
if (root->val == 7) { | ||
// 记录解 | ||
vector *newPath = newVector(); | ||
for (int i = 0; i < path->size; i++) { | ||
vectorPushback(newPath, path->data[i]); | ||
} | ||
vectorPushback(res, newPath); | ||
res->depth++; | ||
} | ||
|
||
preOrder(root->left, path, res); | ||
preOrder(root->right, path, res); | ||
|
||
// 回退 | ||
vectorPopback(path); | ||
} | ||
|
||
// 打印向量中的元素 | ||
void printResult(vector *vv) { | ||
for (int i = 0; i < vv->size; i++) { | ||
vector *v = (vector *)vv->data[i]; | ||
for (int j = 0; j < v->size; j++) { | ||
TreeNode *node = (TreeNode *)v->data[j]; | ||
printf("%d ", node->val); | ||
} | ||
printf("\n"); | ||
} | ||
} | ||
|
||
/* Driver Code */ | ||
int main() { | ||
int arr[] = {1, 7, 3, 4, 5, 6, 7}; | ||
int n = sizeof(arr) / sizeof(arr[0]); | ||
TreeNode *root = arrToTree(arr, n); | ||
printf("\r\n初始化二叉树\r\n"); | ||
printTree(root); | ||
|
||
// 创建存储路径和结果的向量 | ||
vector *path = newVector(); | ||
vector *res = newVector(); | ||
|
||
// 前序遍历 | ||
preOrder(root, path, res); | ||
|
||
// 输出结果 | ||
printf("输出所有根节点到节点 7 的路径,要求路径中不包含值为 3 的节点:\n"); | ||
printResult(res); | ||
|
||
// 释放内存 | ||
delVector(path); | ||
delVector(res); | ||
return 0; | ||
} |
101 changes: 101 additions & 0 deletions
101
codes/c/chapter_backtracking/preorder_traversal_iii_template.c
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
/** | ||
* File: preorder_traversal_iii_template.c | ||
* Created Time: 2023-06-04 | ||
* Author: Gonglja ([email protected]) | ||
*/ | ||
|
||
#include "../utils/common.h" | ||
|
||
/* 判断当前状态是否为解 */ | ||
bool isSolution(vector *state) { | ||
return state->size != 0 && ((TreeNode *)(state->data[state->size - 1]))->val == 7; | ||
} | ||
|
||
/* 记录解 */ | ||
void recordSolution(vector *state, vector *res) { | ||
vector *newPath = newVector(); | ||
for (int i = 0; i < state->size; i++) { | ||
vectorPushback(newPath, state->data[i]); | ||
} | ||
vectorPushback(res, newPath); | ||
} | ||
|
||
/* 判断在当前状态下,该选择是否合法 */ | ||
bool isValid(vector *state, TreeNode *choice) { | ||
return choice != NULL && choice->val != 3; | ||
} | ||
|
||
/* 更新状态 */ | ||
void makeChoice(vector *state, TreeNode *choice) { | ||
vectorPushback(state, choice); | ||
} | ||
|
||
/* 恢复状态 */ | ||
void undoChoice(vector *state, TreeNode *choice) { | ||
vectorPopback(state); | ||
} | ||
|
||
/* 前序遍历:例题三 */ | ||
void backtrack(vector *state, vector *choices, vector *res) { | ||
// 检查是否为解 | ||
if (isSolution(state)) { | ||
// 记录解 | ||
recordSolution(state, res); | ||
return; | ||
} | ||
// 遍历所有选择 | ||
for (int i = 0; i < choices->size; i++) { | ||
TreeNode *choice = choices->data[i]; | ||
// 剪枝:检查选择是否合法 | ||
if (isValid(state, choice)) { | ||
// 尝试:做出选择,更新状态 | ||
makeChoice(state, choice); | ||
// 进行下一轮选择 | ||
vector *nextChoices = newVector(); | ||
vectorPushback(nextChoices, choice->left); | ||
vectorPushback(nextChoices, choice->right); | ||
backtrack(state, nextChoices, res); | ||
// 回退:撤销选择,恢复到之前的状态 | ||
undoChoice(state, choice); | ||
} | ||
} | ||
} | ||
|
||
// 打印向量中的元素 | ||
void printFunc(vector *v, void *p) { | ||
TreeNode *node = p; | ||
printf("%d ", node->val); | ||
} | ||
|
||
/* Driver Code */ | ||
int main() { | ||
int arr[] = {1, 7, 3, 4, 5, 6, 7}; | ||
int n = sizeof(arr) / sizeof(arr[0]); | ||
TreeNode *root = arrToTree(arr, n); | ||
printf("\r\n初始化二叉树\r\n"); | ||
printTree(root); | ||
|
||
// 回溯算法 | ||
vector *state = newVector(); | ||
vector *choices = newVector(); | ||
vector *res = newVector(); | ||
vectorPushback(choices, root); | ||
backtrack(state, choices, res); | ||
|
||
printf("输出所有根节点到节点 7 的路径,要求路径中不包含值为 3 的节点:\n"); | ||
for (int i = 0; i < res->size; i++) { | ||
vector *path = res->data[i]; | ||
vector *vals = newVector(); | ||
for (int j = 0; j < path->size; j++) { | ||
TreeNode *node = path->data[j]; | ||
vectorPushback(vals, &node->val); | ||
} | ||
printVector(vals, printFunc); | ||
} | ||
|
||
// 释放内存 | ||
delVector(state); | ||
delVector(choices); | ||
delVector(res); | ||
return 0; | ||
} |
Oops, something went wrong.