diff --git a/.gitignore b/.gitignore index ccb5e1b1e..52026b066 100644 --- a/.gitignore +++ b/.gitignore @@ -5,8 +5,8 @@ .vscode/ .idea/ cmake-build-debug/ -CMakeLists.txt hello-algo.iml +*.dSYM/ # mkdocs files site/ diff --git a/codes/c/CMakeLists.txt b/codes/c/CMakeLists.txt new file mode 100644 index 000000000..dc9e56af3 --- /dev/null +++ b/codes/c/CMakeLists.txt @@ -0,0 +1,11 @@ +cmake_minimum_required(VERSION 3.10) +project(hello_algo C) + +set(CMAKE_C_STANDARD 11) + +include_directories(./include) + +add_subdirectory(include) +add_subdirectory(chapter_computational_complexity) +add_subdirectory(chapter_array_and_linkedlist) +add_subdirectory(chapter_sorting) diff --git a/codes/c/chapter_array_and_linkedlist/CMakeLists.txt b/codes/c/chapter_array_and_linkedlist/CMakeLists.txt new file mode 100644 index 000000000..24658b301 --- /dev/null +++ b/codes/c/chapter_array_and_linkedlist/CMakeLists.txt @@ -0,0 +1 @@ +add_executable(array array.c) \ No newline at end of file diff --git a/codes/c/chapter_array_and_linkedlist/array.c b/codes/c/chapter_array_and_linkedlist/array.c index 33dc99903..11fcb67f9 100644 --- a/codes/c/chapter_array_and_linkedlist/array.c +++ b/codes/c/chapter_array_and_linkedlist/array.c @@ -74,11 +74,11 @@ int main() { int size = 5; int arr[5]; printf("数组 arr = "); - printArray(arr, size); + PrintArray(arr, size); int nums[5] = { 1, 3, 2, 5, 4 }; printf("数组 nums = "); - printArray(nums, size); + PrintArray(nums, size); /* 随机访问 */ int randomNum = randomAccess(nums, size); @@ -89,17 +89,17 @@ int main() { int* res = extend(nums, size, enlarge); size += enlarge; printf("将数组长度扩展至 8 ,得到 nums = "); - printArray(res, size); + PrintArray(res, size); /* 插入元素 */ insert(res, size, 6, 3); printf("在索引 3 处插入数字 6 ,得到 nums = "); - printArray(res, size); + PrintArray(res, size); /* 删除元素 */ removeItem(res, size, 2); printf("删除索引 2 处的元素,得到 nums = "); - printArray(res, size); + PrintArray(res, size); /* 遍历数组 */ traverse(res, size); diff --git a/codes/c/chapter_computational_complexity/CMakeLists.txt b/codes/c/chapter_computational_complexity/CMakeLists.txt new file mode 100644 index 000000000..d9e55dcf1 --- /dev/null +++ b/codes/c/chapter_computational_complexity/CMakeLists.txt @@ -0,0 +1,2 @@ +add_executable(time_complexity time_complexity.c ) +add_executable(worst_best_time_complexity worst_best_time_complexity.c) \ No newline at end of file diff --git a/codes/c/chapter_computational_complexity/worst_best_time_complexity.c b/codes/c/chapter_computational_complexity/worst_best_time_complexity.c index 2570ff3c3..531a76e51 100644 --- a/codes/c/chapter_computational_complexity/worst_best_time_complexity.c +++ b/codes/c/chapter_computational_complexity/worst_best_time_complexity.c @@ -41,7 +41,7 @@ int main(int argc, char *argv[]) { int *nums = randomNumbers(n); int index = findOne(nums, n); printf("\n数组 [ 1, 2, ..., n ] 被打乱后 = "); - printArray(nums, n); + PrintArray(nums, n); printf("数字 1 的索引为 %d\n", index); // 释放堆区内存 if (nums != NULL) { @@ -49,6 +49,5 @@ int main(int argc, char *argv[]) { nums = NULL; } } - getchar(); return 0; } diff --git a/codes/c/chapter_sorting/CMakeLists.txt b/codes/c/chapter_sorting/CMakeLists.txt new file mode 100644 index 000000000..192e1cb97 --- /dev/null +++ b/codes/c/chapter_sorting/CMakeLists.txt @@ -0,0 +1,2 @@ +add_executable(bubble_sort bubble_sort.c) +add_executable(insertion_sort insertion_sort.c) \ No newline at end of file diff --git a/codes/c/chapter_sorting/bubble_sort.c b/codes/c/chapter_sorting/bubble_sort.c index 5c74d9e4e..4a2a24b44 100644 --- a/codes/c/chapter_sorting/bubble_sort.c +++ b/codes/c/chapter_sorting/bubble_sort.c @@ -50,14 +50,14 @@ void bubble_sort_with_flag(int nums[], int size) { /* Driver Code */ int main() { int nums[6] = {4, 1, 3, 1, 5, 2}; - printf("冒泡排序后:\n"); + printf("冒泡排序后: "); bubble_sort(nums, 6); for (int i = 0; i < 6; i++) { printf("%d ", nums[i]); } - printf("优化版冒泡排序后:\n"); + printf("\n优化版冒泡排序后: "); bubble_sort_with_flag(nums, 6); for (int i = 0; i < 6; i++) { diff --git a/codes/c/chapter_sorting/insertion_sort.c b/codes/c/chapter_sorting/insertion_sort.c index 80e8b127b..f81b8d43e 100644 --- a/codes/c/chapter_sorting/insertion_sort.c +++ b/codes/c/chapter_sorting/insertion_sort.c @@ -28,7 +28,7 @@ void insertionSort(int nums[], int size) { int main() { int nums[] = {4, 1, 3, 1, 5, 2}; insertionSort(nums, 6); - printf("插入排序完成后 nums = \n"); + printf("插入排序完成后 nums = "); for (int i = 0; i < 6; i++) { printf("%d ", nums[i]); diff --git a/codes/c/include/CMakeLists.txt b/codes/c/include/CMakeLists.txt new file mode 100644 index 000000000..4189ae334 --- /dev/null +++ b/codes/c/include/CMakeLists.txt @@ -0,0 +1,4 @@ +add_executable(include + include_test.c + include.h print_util.h + list_node.h tree_node.h) \ No newline at end of file diff --git a/codes/c/include/PrintUtil.h b/codes/c/include/PrintUtil.h deleted file mode 100644 index 59a8eac1b..000000000 --- a/codes/c/include/PrintUtil.h +++ /dev/null @@ -1,28 +0,0 @@ -/** - * File: PrintUtil.h - * Created Time: 2022-12-21 - * Author: MolDum (moldum@163.com) - */ - -#include -#include -#include - -// #include "ListNode.h" -// #include "TreeNode.h" - -/** - * @brief Print an Array - * - * @param arr - * @param n - */ - -static void printArray(int* arr, int n) -{ - printf("["); - for (int i = 0; i < n - 1; i++) { - printf("%d, ", arr[i]); - } - printf("%d]\n", arr[n-1]); -} diff --git a/codes/c/include/include.h b/codes/c/include/include.h index 2c4fd9252..9f30b0529 100644 --- a/codes/c/include/include.h +++ b/codes/c/include/include.h @@ -1,13 +1,28 @@ /** * File: include.h * Created Time: 2022-12-20 - * Author: MolDuM (moldum@163.com) + * Author: MolDuM (moldum@163.com)、Reanon (793584285@qq.com) */ +#ifndef C_INCLUDE_H +#define C_INCLUDE_H + #include #include #include #include #include -#include "PrintUtil.h" +#include "list_node.h" +#include "tree_node.h" +#include "print_util.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef __cplusplus +} +#endif + +#endif // C_INCLUDE_H diff --git a/codes/c/include/include_test.c b/codes/c/include/include_test.c new file mode 100644 index 000000000..baa8e649d --- /dev/null +++ b/codes/c/include/include_test.c @@ -0,0 +1,38 @@ +/** + * File: include_test.c + * Created Time: 2023-01-10 + * Author: Reanon (793584285@qq.com) + */ + +#include "include.h" + +void testListNode() { + int nums[] = {2, 3, 5, 6, 7}; + int size = sizeof(nums) / sizeof(int); + ListNode *head = ArrayToLinkedList(nums, size); + PrintLinkedList(head); + + ListNode *node = GetListNode(head, 5); + printf("find node: %d\n", node->val); +} + +void testTreeNode() { + int nums[] = {1, 2, 3, NIL, 5, 6, NIL}; + int size = sizeof(nums) / sizeof(int); + TreeNode *root = ArrayToTree(nums, size); + + // print tree + PrintTree(root); + + // tree to arr + int *arr = TreeToArray(root); + PrintArray(arr, size); +} + +int main(int argc, char *argv[]) { + printf("==testListNode==\n"); + testListNode(); + printf("==testTreeNode==\n"); + testTreeNode(); + return 0; +} diff --git a/codes/c/include/list_node.h b/codes/c/include/list_node.h new file mode 100644 index 000000000..5597d2102 --- /dev/null +++ b/codes/c/include/list_node.h @@ -0,0 +1,72 @@ +/** + * File: list_node.h + * Created Time: 2023-01-09 + * Author: Reanon (793584285@qq.com) + */ +#ifndef LIST_NODE_H +#define LIST_NODE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Definition for a singly-linked list node + * + */ +struct ListNode { + int val; // 结点值 + struct ListNode *next; // 指向下一结点的指针(引用) +}; + +// typedef 为 C 语言的关键字,作用是为一种数据类型定义一个新名字 +typedef struct ListNode ListNode; + +ListNode *NewListNode(int val) { + ListNode *node, *next; + node = (ListNode *) malloc(sizeof(ListNode)); + node->val = val; + node->next = NULL; + return node; +} + +/** + * @brief Generate a linked list with a vector + * + * @param list + * @return ListNode* + */ + +ListNode *ArrayToLinkedList(const int *arr, size_t size) { + if (size <= 0) { + return NULL; + } + + ListNode *dummy = NewListNode(0); + ListNode *node = dummy; + for (int i = 0; i < size; i++) { + node->next = NewListNode(arr[i]); + node = node->next; + } + return dummy->next; +} + +/** + * @brief Get a list node with specific value from a linked list + * + * @param head + * @param val + * @return ListNode* + */ +ListNode *GetListNode(ListNode *head, int val) { + while (head != NULL && head->val != val) { + head = head->next; + } + return head; +} + +#ifdef __cplusplus +} +#endif + +#endif // LIST_NODE_H \ No newline at end of file diff --git a/codes/c/include/print_util.h b/codes/c/include/print_util.h new file mode 100644 index 000000000..fcb0a4ca6 --- /dev/null +++ b/codes/c/include/print_util.h @@ -0,0 +1,135 @@ +/** + * File: print_util.h + * Created Time: 2022-12-21 + * Author: MolDum (moldum@163.com)、Reanon (793584285@qq.com) + */ + +#ifndef PRINT_UTIL_H +#define PRINT_UTIL_H + +#include +#include +#include + +#include "list_node.h" +#include "tree_node.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +/** + * @brief Print an Array + * + * @param arr + * @param size + */ +static void PrintArray(int *arr, int size) { + printf("["); + for (int i = 0; i < size - 1; i++) { + if (arr[i] != NIL) { + printf("%d, ", arr[i]); + } else { + printf("NULL, "); + } + } + if (arr[size - 1] != NIL) { + printf("%d]\n", arr[size - 1]); + }else{ + printf("NULL]\n"); + } +} + +/** + * @brief Print a linked list + * + * @param head + */ +static void PrintLinkedList(ListNode *node) { + if (node == NULL) { + return; + } + while (node->next != NULL) { + printf("%d -> ", node->val); + node = node->next; + } + printf("%d\n", node->val); +} + +struct Trunk { + struct Trunk *prev; + char *str; +}; + +typedef struct Trunk Trunk; + +Trunk *newTrunk(Trunk *prev, char *str) { + Trunk *trunk = (Trunk *) malloc(sizeof(Trunk)); + trunk->prev = prev; + trunk->str = (char *) malloc(sizeof(char) * 10); + strcpy(trunk->str, str); + return trunk; +} + +/** + * @brief Helper function to print branches of the binary tree + * + * @param trunk + */ +void showTrunks(Trunk *trunk) { + if (trunk == NULL) { + return; + } + showTrunks(trunk->prev); + printf("%s", trunk->str); +} + +/** + * Help to print a binary tree, hide more details + * @param node + * @param prev + * @param isLeft + */ +static void printTreeHelper(TreeNode *node, Trunk *prev, bool isLeft) { + if (node == NULL) { + return; + } + char *prev_str = " "; + Trunk *trunk = newTrunk(prev, prev_str); + printTreeHelper(node->right, trunk, true); + if (prev == NULL) { + trunk->str = "———"; + } else if (isLeft) { + trunk->str = "/———"; + prev_str = " |"; + } else { + trunk->str = "\\———"; + prev->str = prev_str; + } + showTrunks(trunk); + printf("%d\n", node->val); + + if (prev != NULL) { + prev->str = prev_str; + } + trunk->str = " |"; + + printTreeHelper(node->left, trunk, false); +} + +/** + * @brief Print a binary tree + * + * @param head + */ +static void PrintTree(TreeNode *root) { + printTreeHelper(root, NULL, false); +} + + +#ifdef __cplusplus +} +#endif + +#endif // PRINT_UTIL_H diff --git a/codes/c/include/tree_node.h b/codes/c/include/tree_node.h new file mode 100644 index 000000000..4b0e70187 --- /dev/null +++ b/codes/c/include/tree_node.h @@ -0,0 +1,131 @@ +/** + * File: tree_node.h + * Created Time: 2023-01-09 + * Author: Reanon (793584285@qq.com) + */ + + +#ifndef TREE_NODE_H +#define TREE_NODE_H + +#ifdef __cplusplus +extern "C" { +#endif + +#define NIL ('#') +#define MAX_NODE_SIZE 5000 + +struct TreeNode { + int val; + int height; + struct TreeNode *left; + struct TreeNode *right; +}; + +typedef struct TreeNode TreeNode; + + +TreeNode *NewTreeNode(int val) { + TreeNode *node; + + node = (TreeNode *) malloc(sizeof(TreeNode)); + node->val = val; + node->height = 0; + node->left = NULL; + node->right = NULL; + return node; +} + +/** + * @brief Generate a binary tree with an array + * + * @param arr + * @param size + * @return TreeNode * + */ +TreeNode *ArrayToTree(const int *arr, size_t size) { + if (size <= 0) { + return NULL; + } + + int front, rear, index; + TreeNode *root, *node; + TreeNode **queue; + + /* 根结点 */ + root = NewTreeNode(arr[0]); + /* 辅助队列 */ + queue = (TreeNode **) malloc(sizeof(TreeNode) * MAX_NODE_SIZE); + // 队列指针 + front = 0, rear = 0; + // 将根结点放入队尾 + queue[rear++] = root; + // 记录遍历数组的索引 + index = 0; + while (front < rear) { + // 取队列中的头结点,并让头结点出队 + node = queue[front++]; + index++; + if (index < size) { + if (arr[index] != NIL) { + node->left = NewTreeNode(arr[index]); + queue[rear++] = node->left; + } + } + index++; + if (index < size) { + if (arr[index] != NIL) { + node->right = NewTreeNode(arr[index]); + queue[rear++] = node->right; + } + } + } + return root; +} + + +/** + * @brief Generate a binary tree with an array + * + * @param arr + * @param size + * @return TreeNode * + */ +int *TreeToArray(TreeNode *root) { + if (root == NULL) { + return NULL; + } + int front, rear; + int index, *arr; + TreeNode *node; + TreeNode **queue; + /* 辅助队列 */ + queue = (TreeNode **) malloc(sizeof(TreeNode) * MAX_NODE_SIZE); + // 队列指针 + front = 0, rear = 0; + // 将根结点放入队尾 + queue[rear++] = root; + /* 辅助数组 */ + arr = (int *) malloc(sizeof(int) * MAX_NODE_SIZE); + // 数组指针 + index = 0; + while (front < rear) { + // 取队列中的头结点,并让头结点出队 + node = queue[front++]; + if (node != NULL) { + arr[index] = node->val; + queue[rear++] = node->left; + queue[rear++] = node->right; + } else { + arr[index] = NIL; + } + index++; + } + return arr; +} + +#ifdef __cplusplus +} +#endif + +#endif // TREE_NODE_H