mirror of
				https://github.com/krahets/hello-algo.git
				synced 2025-11-04 22:28:40 +08:00 
			
		
		
		
	feat: Add C codes for the chapter backtracking (#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 <krahets@163.com>
This commit is contained in:
		@ -11,6 +11,7 @@ add_subdirectory(chapter_stack_and_queue)
 | 
				
			|||||||
add_subdirectory(chapter_heap)
 | 
					add_subdirectory(chapter_heap)
 | 
				
			||||||
add_subdirectory(chapter_hashing)
 | 
					add_subdirectory(chapter_hashing)
 | 
				
			||||||
add_subdirectory(chapter_tree)
 | 
					add_subdirectory(chapter_tree)
 | 
				
			||||||
 | 
					add_subdirectory(chapter_graph)
 | 
				
			||||||
add_subdirectory(chapter_searching)
 | 
					add_subdirectory(chapter_searching)
 | 
				
			||||||
add_subdirectory(chapter_sorting)
 | 
					add_subdirectory(chapter_sorting)
 | 
				
			||||||
add_subdirectory(chapter_graph)
 | 
					add_subdirectory(chapter_backtracking)
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										8
									
								
								codes/c/chapter_backtracking/CMakeLists.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								codes/c/chapter_backtracking/CMakeLists.txt
									
									
									
									
									
										Normal file
									
								
							@ -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)
 | 
				
			||||||
							
								
								
									
										81
									
								
								codes/c/chapter_backtracking/permutations_i.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										81
									
								
								codes/c/chapter_backtracking/permutations_i.c
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,81 @@
 | 
				
			|||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * File: permutations_i.c
 | 
				
			||||||
 | 
					 * Created Time: 2023-06-04
 | 
				
			||||||
 | 
					 * Author: Gonglja (glj0@outlook.com)
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#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
									
								
								codes/c/chapter_backtracking/preorder_traversal_i_compact.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								codes/c/chapter_backtracking/preorder_traversal_i_compact.c
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,44 @@
 | 
				
			|||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * File: preorder_traversal_i_compact.c
 | 
				
			||||||
 | 
					 * Created Time: 2023-05-10
 | 
				
			||||||
 | 
					 * Author: Gonglja (glj0@outlook.com)
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#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
									
								
								codes/c/chapter_backtracking/preorder_traversal_ii_compact.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										67
									
								
								codes/c/chapter_backtracking/preorder_traversal_ii_compact.c
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,67 @@
 | 
				
			|||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * File: preorder_traversal_ii_compact.c
 | 
				
			||||||
 | 
					 * Created Time: 2023-05-28
 | 
				
			||||||
 | 
					 * Author: Gonglja (glj0@outlook.com)
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#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;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -0,0 +1,69 @@
 | 
				
			|||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * File: preorder_traversal_iii_compact.c
 | 
				
			||||||
 | 
					 * Created Time: 2023-06-04
 | 
				
			||||||
 | 
					 * Author: Gonglja (glj0@outlook.com)
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#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
									
								
								codes/c/chapter_backtracking/preorder_traversal_iii_template.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										101
									
								
								codes/c/chapter_backtracking/preorder_traversal_iii_template.c
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,101 @@
 | 
				
			|||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * File: preorder_traversal_iii_template.c
 | 
				
			||||||
 | 
					 * Created Time: 2023-06-04
 | 
				
			||||||
 | 
					 * Author: Gonglja (glj0@outlook.com)
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#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;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										76
									
								
								codes/c/chapter_backtracking/subset_sum_i.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										76
									
								
								codes/c/chapter_backtracking/subset_sum_i.c
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,76 @@
 | 
				
			|||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * File: subset_sum_i.c
 | 
				
			||||||
 | 
					 * Created Time: 2023-07-29
 | 
				
			||||||
 | 
					 * Author: Gonglja (glj0@outlook.com)
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "../utils/common.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* 回溯算法:子集和 I */
 | 
				
			||||||
 | 
					void backtrack(vector *state, int target, vector *choices, int start, vector *res) {
 | 
				
			||||||
 | 
					    // 子集和等于 target 时,记录解
 | 
				
			||||||
 | 
					    if (target == 0) {
 | 
				
			||||||
 | 
					        vector *tmpVector = newVector();
 | 
				
			||||||
 | 
					        for (int i = 0; i < state->size; i++) {
 | 
				
			||||||
 | 
					            vectorPushback(tmpVector, state->data[i]);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        vectorPushback(res, tmpVector);
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    // 遍历所有选择
 | 
				
			||||||
 | 
					    // 剪枝二:从 start 开始遍历,避免生成重复子集
 | 
				
			||||||
 | 
					    for (int i = start; i < choices->size; i++) {
 | 
				
			||||||
 | 
					        // 剪枝:若子集和超过 target ,则跳过该选择
 | 
				
			||||||
 | 
					        if (target - *(int *)(choices->data[i]) < 0) {
 | 
				
			||||||
 | 
					            continue;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        // 尝试:做出选择,更新 target, start
 | 
				
			||||||
 | 
					        vectorPushback(state, choices->data[i]);
 | 
				
			||||||
 | 
					        // 进行下一轮选择
 | 
				
			||||||
 | 
					        backtrack(state, target - *(int *)(choices->data[i]), choices, i, res);
 | 
				
			||||||
 | 
					        // 回退:撤销选择,恢复到之前的状态
 | 
				
			||||||
 | 
					        vectorPopback(state);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* 用来做比较的函数 */
 | 
				
			||||||
 | 
					int comp(const void *a, const void *b) {
 | 
				
			||||||
 | 
					    return *(int *)a - *(int *)b;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* 求解子集和 I */
 | 
				
			||||||
 | 
					vector *subsetSumINaive(vector *nums, int target) {
 | 
				
			||||||
 | 
					    vector *state = newVector();                         // 状态(子集)
 | 
				
			||||||
 | 
					    qsort(nums->data[0], nums->size, sizeof(int), comp); // 对 nums 进行排序
 | 
				
			||||||
 | 
					    int start = 0;                                       // 子集和
 | 
				
			||||||
 | 
					    vector *res = newVector();                           // 结果列表(子集列表)
 | 
				
			||||||
 | 
					    backtrack(state, target, nums, start, res);
 | 
				
			||||||
 | 
					    return res;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* 打印向量中的元素 */
 | 
				
			||||||
 | 
					void printFunc(vector *v, void *p) {
 | 
				
			||||||
 | 
					    TreeNode *node = p;
 | 
				
			||||||
 | 
					    printf("%d", node->val);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Driver Code */
 | 
				
			||||||
 | 
					int main() {
 | 
				
			||||||
 | 
					    int nums[] = {3, 4, 5};
 | 
				
			||||||
 | 
					    vector *vNums = newVector();
 | 
				
			||||||
 | 
					    for (int i = 0; i < sizeof(nums) / sizeof(nums[0]); i++) {
 | 
				
			||||||
 | 
					        vectorPushback(vNums, &nums[i]);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    int target = 9;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    vector *res = subsetSumINaive(vNums, target);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    printf("输入数组 nums = ");
 | 
				
			||||||
 | 
					    printVector(vNums, printFunc);
 | 
				
			||||||
 | 
					    printf("target = %d\n", target);
 | 
				
			||||||
 | 
					    printf("所有和等于 %d 的子集 res = \r\n", target);
 | 
				
			||||||
 | 
					    printVectorMatrix(res, printFunc);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    delVector(res);
 | 
				
			||||||
 | 
					    return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										69
									
								
								codes/c/chapter_backtracking/subset_sum_i_naive.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										69
									
								
								codes/c/chapter_backtracking/subset_sum_i_naive.c
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,69 @@
 | 
				
			|||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * File: subset_sum_i_naive.c
 | 
				
			||||||
 | 
					 * Created Time: 2023-07-28
 | 
				
			||||||
 | 
					 * Author: Gonglja (glj0@outlook.com)
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "../utils/common.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* 回溯算法:子集和 I */
 | 
				
			||||||
 | 
					void backtrack(vector *state, int target, int total, vector *choices, vector *res) {
 | 
				
			||||||
 | 
					    // 子集和等于 target 时,记录解
 | 
				
			||||||
 | 
					    if (total == target) {
 | 
				
			||||||
 | 
					        vector *tmpVector = newVector();
 | 
				
			||||||
 | 
					        for (int i = 0; i < state->size; i++) {
 | 
				
			||||||
 | 
					            vectorPushback(tmpVector, state->data[i]);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        vectorPushback(res, tmpVector);
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    // 遍历所有选择
 | 
				
			||||||
 | 
					    for (size_t i = 0; i < choices->size; i++) {
 | 
				
			||||||
 | 
					        // 剪枝:若子集和超过 target ,则跳过该选择
 | 
				
			||||||
 | 
					        if (total + *(int *)(choices->data[i]) > target) {
 | 
				
			||||||
 | 
					            continue;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        // 尝试:做出选择,更新元素和 total
 | 
				
			||||||
 | 
					        vectorPushback(state, choices->data[i]);
 | 
				
			||||||
 | 
					        // 进行下一轮选择
 | 
				
			||||||
 | 
					        backtrack(state, target, total + *(int *)(choices->data[i]), choices, res);
 | 
				
			||||||
 | 
					        // 回退:撤销选择,恢复到之前的状态
 | 
				
			||||||
 | 
					        vectorPopback(state);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* 求解子集和 I(包含重复子集) */
 | 
				
			||||||
 | 
					vector *subsetSumINaive(vector *nums, int target) {
 | 
				
			||||||
 | 
					    vector *state = newVector(); // 状态(子集)
 | 
				
			||||||
 | 
					    int total = 0;               // 子集和
 | 
				
			||||||
 | 
					    vector *res = newVector();   // 结果列表(子集列表)
 | 
				
			||||||
 | 
					    backtrack(state, target, total, nums, res);
 | 
				
			||||||
 | 
					    return res;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* 打印向量中的元素 */
 | 
				
			||||||
 | 
					void printFunc(vector *v, void *p) {
 | 
				
			||||||
 | 
					    TreeNode *node = p;
 | 
				
			||||||
 | 
					    printf("%d", node->val);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Driver Code */
 | 
				
			||||||
 | 
					int main() {
 | 
				
			||||||
 | 
					    int nums[] = {3, 4, 5};
 | 
				
			||||||
 | 
					    vector *vNums = newVector();
 | 
				
			||||||
 | 
					    for (int i = 0; i < sizeof(nums) / sizeof(nums[0]); i++) {
 | 
				
			||||||
 | 
					        vectorPushback(vNums, &nums[i]);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    int target = 9;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    vector *res = subsetSumINaive(vNums, target);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    printf("输入数组 nums = ");
 | 
				
			||||||
 | 
					    printVector(vNums, printFunc);
 | 
				
			||||||
 | 
					    printf("target = %d\n", target);
 | 
				
			||||||
 | 
					    printf("所有和等于 %d 的子集 res = \r\n", target);
 | 
				
			||||||
 | 
					    printVectorMatrix(res, printFunc);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    delVector(res);
 | 
				
			||||||
 | 
					    return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										83
									
								
								codes/c/chapter_backtracking/subset_sum_ii.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										83
									
								
								codes/c/chapter_backtracking/subset_sum_ii.c
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,83 @@
 | 
				
			|||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * File: subset_sum_ii.c
 | 
				
			||||||
 | 
					 * Created Time: 2023-07-29
 | 
				
			||||||
 | 
					 * Author: Gonglja (glj0@outlook.com)
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "../utils/common.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* 回溯算法:子集和 I */
 | 
				
			||||||
 | 
					void backtrack(vector *state, int target, vector *choices, int start, vector *res) {
 | 
				
			||||||
 | 
					    // 子集和等于 target 时,记录解
 | 
				
			||||||
 | 
					    if (target == 0) {
 | 
				
			||||||
 | 
					        vector *tmpVector = newVector();
 | 
				
			||||||
 | 
					        for (int i = 0; i < state->size; i++) {
 | 
				
			||||||
 | 
					            vectorPushback(tmpVector, state->data[i]);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        vectorPushback(res, tmpVector);
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    // 遍历所有选择
 | 
				
			||||||
 | 
					    // 剪枝二:从 start 开始遍历,避免生成重复子集
 | 
				
			||||||
 | 
					    // 剪枝三:从 start 开始遍历,避免重复选择同一元素
 | 
				
			||||||
 | 
					    for (int i = start; i < choices->size; i++) {
 | 
				
			||||||
 | 
					        // 剪枝一:若子集和超过 target ,则直接结束循环
 | 
				
			||||||
 | 
					        // 这是因为数组已排序,后边元素更大,子集和一定超过 target
 | 
				
			||||||
 | 
					        if (target - *(int *)(choices->data[i]) < 0) {
 | 
				
			||||||
 | 
					            continue;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // 剪枝四:如果该元素与左边元素相等,说明该搜索分支重复,直接跳过
 | 
				
			||||||
 | 
					        if (i > start && *(int *)(choices->data[i]) == *(int *)(choices->data[i - 1])) {
 | 
				
			||||||
 | 
					            continue;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        // 尝试:做出选择,更新 target, start
 | 
				
			||||||
 | 
					        vectorPushback(state, choices->data[i]);
 | 
				
			||||||
 | 
					        // 进行下一轮选择
 | 
				
			||||||
 | 
					        backtrack(state, target - *(int *)(choices->data[i]), choices, i + 1, res);
 | 
				
			||||||
 | 
					        // 回退:撤销选择,恢复到之前的状态
 | 
				
			||||||
 | 
					        vectorPopback(state);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* 用来做比较的函数 */
 | 
				
			||||||
 | 
					int comp(const void *a, const void *b) {
 | 
				
			||||||
 | 
					    return *(int *)a - *(int *)b;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* 求解子集和 I */
 | 
				
			||||||
 | 
					vector *subsetSumINaive(vector *nums, int target) {
 | 
				
			||||||
 | 
					    vector *state = newVector();                         // 状态(子集)
 | 
				
			||||||
 | 
					    qsort(nums->data[0], nums->size, sizeof(int), comp); // 对 nums 进行排序
 | 
				
			||||||
 | 
					    int start = 0;                                       // 子集和
 | 
				
			||||||
 | 
					    vector *res = newVector();                           // 结果列表(子集列表)
 | 
				
			||||||
 | 
					    backtrack(state, target, nums, start, res);
 | 
				
			||||||
 | 
					    return res;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* 打印向量中的元素 */
 | 
				
			||||||
 | 
					void printFunc(vector *v, void *p) {
 | 
				
			||||||
 | 
					    TreeNode *node = p;
 | 
				
			||||||
 | 
					    printf("%d", node->val);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Driver Code */
 | 
				
			||||||
 | 
					int main() {
 | 
				
			||||||
 | 
					    int nums[] = {4, 4, 5};
 | 
				
			||||||
 | 
					    vector *vNums = newVector();
 | 
				
			||||||
 | 
					    for (int i = 0; i < sizeof(nums) / sizeof(nums[0]); i++) {
 | 
				
			||||||
 | 
					        vectorPushback(vNums, &nums[i]);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    int target = 9;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    vector *res = subsetSumINaive(vNums, target);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    printf("输入数组 nums = ");
 | 
				
			||||||
 | 
					    printVector(vNums, printFunc);
 | 
				
			||||||
 | 
					    printf("target = %d\n", target);
 | 
				
			||||||
 | 
					    printf("所有和等于 %d 的子集 res = \r\n", target);
 | 
				
			||||||
 | 
					    printVectorMatrix(res, printFunc);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    delVector(res);
 | 
				
			||||||
 | 
					    return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -21,6 +21,8 @@
 | 
				
			|||||||
// hash table lib
 | 
					// hash table lib
 | 
				
			||||||
#include "uthash.h"
 | 
					#include "uthash.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "vector.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef __cplusplus
 | 
					#ifdef __cplusplus
 | 
				
			||||||
extern "C" {
 | 
					extern "C" {
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										139
									
								
								codes/c/utils/vector.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										139
									
								
								codes/c/utils/vector.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,139 @@
 | 
				
			|||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * File: vector.h
 | 
				
			||||||
 | 
					 * Created Time: 2023-07-13
 | 
				
			||||||
 | 
					 * Author: Gonglja (glj0@outlook.com)
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef VECTOR_H
 | 
				
			||||||
 | 
					#define VECTOR_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef __cplusplus
 | 
				
			||||||
 | 
					extern "C" {
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* 定义向量类型 */
 | 
				
			||||||
 | 
					typedef struct vector {
 | 
				
			||||||
 | 
					    int size;     // 当前向量的大小
 | 
				
			||||||
 | 
					    int capacity; // 当前向量的容量
 | 
				
			||||||
 | 
					    int depth;    // 当前向量的深度
 | 
				
			||||||
 | 
					    void **data;  // 指向数据的指针数组
 | 
				
			||||||
 | 
					} vector;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* 构造向量 */
 | 
				
			||||||
 | 
					vector *newVector() {
 | 
				
			||||||
 | 
					    vector *v = malloc(sizeof(vector));
 | 
				
			||||||
 | 
					    v->size = 0;
 | 
				
			||||||
 | 
					    v->capacity = 4;
 | 
				
			||||||
 | 
					    v->depth = 1;
 | 
				
			||||||
 | 
					    v->data = malloc(v->capacity * sizeof(void *));
 | 
				
			||||||
 | 
					    return v;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* 析构向量 */
 | 
				
			||||||
 | 
					void delVector(vector *v) {
 | 
				
			||||||
 | 
					    if (v) {
 | 
				
			||||||
 | 
					        if (v->depth == 0) {
 | 
				
			||||||
 | 
					            return;
 | 
				
			||||||
 | 
					        } else if (v->depth == 1) {
 | 
				
			||||||
 | 
					            for (int i = 0; i < v->size; i++) {
 | 
				
			||||||
 | 
					                free(v->data[i]);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            free(v);
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            for (int i = 0; i < v->size; i++) {
 | 
				
			||||||
 | 
					                delVector(v->data[i]);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            v->depth--;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*  添加元素到向量尾部 */
 | 
				
			||||||
 | 
					void vectorPushback(vector *v, void *elem) {
 | 
				
			||||||
 | 
					    if (v->size == v->capacity) {
 | 
				
			||||||
 | 
					        v->capacity *= 2;
 | 
				
			||||||
 | 
					        v->data = realloc(v->data, v->capacity * sizeof(void *));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    v->data[v->size++] = elem;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* 从向量尾部弹出元素 */
 | 
				
			||||||
 | 
					void vectorPopback(vector *v) {
 | 
				
			||||||
 | 
					    if (v->size != 0) {
 | 
				
			||||||
 | 
					        v->size--;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* 清空向量 */
 | 
				
			||||||
 | 
					void vectorClear(vector *v) {
 | 
				
			||||||
 | 
					    delVector(v);
 | 
				
			||||||
 | 
					    v->size = 0;
 | 
				
			||||||
 | 
					    v->capacity = 4;
 | 
				
			||||||
 | 
					    v->depth = 1;
 | 
				
			||||||
 | 
					    v->data = malloc(v->capacity * sizeof(void *));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* 获取向量的大小 */
 | 
				
			||||||
 | 
					int vectorSize(vector *v) {
 | 
				
			||||||
 | 
					    return v->size;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* 获取向量的尾元素 */
 | 
				
			||||||
 | 
					void *vectorBack(vector *v) {
 | 
				
			||||||
 | 
					    return v->data[v->size];
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* 获取向量的头元素 */
 | 
				
			||||||
 | 
					void *vectorFront(vector *v) {
 | 
				
			||||||
 | 
					    return v->data[0];
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* 打印函数, 需传递一个打印变量的函数进来 */
 | 
				
			||||||
 | 
					/* 当前仅支持打印深度为 1 的 vector*/
 | 
				
			||||||
 | 
					void printVector(vector *v, void (*printFunc)(vector *v, void *p)) {
 | 
				
			||||||
 | 
					    if (v) {
 | 
				
			||||||
 | 
					        if (v->depth == 0) {
 | 
				
			||||||
 | 
					            return;
 | 
				
			||||||
 | 
					        } else if (v->depth == 1) {
 | 
				
			||||||
 | 
					            for (int i = 0; i < v->size; i++) {
 | 
				
			||||||
 | 
									if (i == 0) {
 | 
				
			||||||
 | 
										printf("[");
 | 
				
			||||||
 | 
									} else if (i == v->size-1) {
 | 
				
			||||||
 | 
										printFunc(v, v->data[i]);
 | 
				
			||||||
 | 
										printf("]\r\n");
 | 
				
			||||||
 | 
										break;
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									printFunc(v, v->data[i]);
 | 
				
			||||||
 | 
									printf(",");
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            for (int i = 0; i < v->size; i++) {
 | 
				
			||||||
 | 
					                printVector(v->data[i], printFunc);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            v->depth--;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* 当前仅支持打印深度为 2 的 vector */
 | 
				
			||||||
 | 
					void printVectorMatrix(vector *vv, void (*printFunc)(vector *v, void *p)) {
 | 
				
			||||||
 | 
						printf("[\n");
 | 
				
			||||||
 | 
						for (int i = 0; i < vv->size; i++) {
 | 
				
			||||||
 | 
							vector *v = (vector *)vv->data[i];
 | 
				
			||||||
 | 
							printf("  [");
 | 
				
			||||||
 | 
							for (int j = 0; j < v->size; j++) {
 | 
				
			||||||
 | 
								printFunc(v, v->data[j]);
 | 
				
			||||||
 | 
								if (j != v->size -1)
 | 
				
			||||||
 | 
									printf(",");
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							printf("],");
 | 
				
			||||||
 | 
							printf("\n");
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						printf("]\n");
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef __cplusplus
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif // VECTOR_H
 | 
				
			||||||
		Reference in New Issue
	
	Block a user