diff --git a/codes/c/CMakeLists.txt b/codes/c/CMakeLists.txt index 3b239e7e6..623a0c15f 100644 --- a/codes/c/CMakeLists.txt +++ b/codes/c/CMakeLists.txt @@ -10,4 +10,5 @@ add_subdirectory(chapter_computational_complexity) add_subdirectory(chapter_array_and_linkedlist) add_subdirectory(chapter_sorting) add_subdirectory(chapter_tree) -add_subdirectory(chapter_heap) +add_subdirectory(chapter_stack_and_queue) +add_subdirectory(chapter_heap) \ No newline at end of file diff --git a/codes/c/chapter_array_and_linkedlist/CMakeLists.txt b/codes/c/chapter_array_and_linkedlist/CMakeLists.txt index dfa3322fb..29677a0be 100644 --- a/codes/c/chapter_array_and_linkedlist/CMakeLists.txt +++ b/codes/c/chapter_array_and_linkedlist/CMakeLists.txt @@ -1,2 +1,3 @@ add_executable(array array.c) -add_executable(linked_list linked_list.c) \ No newline at end of file +add_executable(linked_list linked_list.c) +add_executable(my_list my_list.c) \ No newline at end of file diff --git a/codes/c/chapter_array_and_linkedlist/my_list.c b/codes/c/chapter_array_and_linkedlist/my_list.c new file mode 100644 index 000000000..879d74333 --- /dev/null +++ b/codes/c/chapter_array_and_linkedlist/my_list.c @@ -0,0 +1,159 @@ +/** + * File: list.c + * Created Time: 2022-01-12 + * Author: Zero (glj0@outlook.com) + */ + +#include "../include/include.h" + + +// 用数组实现 list +struct mylist { + int* nums; // 数组(存储列表元素) + int capacity; // 列表容量 + int size; // 列表大小 + int extendRatio; // 列表每次扩容的倍数 +}; + +typedef struct mylist MyList; +/* 前置声明 */ +void extendCapacity(MyList *list); + +/* 构造函数 */ +void newMyList(MyList *list) { + list->capacity = 10; + list->nums = malloc(sizeof(int) * list->capacity); + list->size = 0; + list->extendRatio = 2; +} + +/* 析构函数 */ +void delMyList(MyList *list) { + list->size = 0; + free(list->nums); +} + +/* 获取列表长度 */ +int size(MyList *list) { + return list->size; +} + +/* 获取列表容量 */ +int capacity(MyList *list) { + return list->capacity; +} + +/* 访问元素 */ +int get(MyList *list, int index) { + assert(index < list->size); + return list->nums[index]; +} + +/* 更新元素 */ +void set(MyList *list, int index, int num) { + assert(index < list->size); + list->nums[index] = num; +} + +/* 尾部添加元素 */ +void add(MyList *list, int num) { + if (size(list) == capacity(list)) { + extendCapacity(list); // 扩容 + } + list->nums[size(list)] = num; + list->size++; +} + +/* 中间插入元素 */ +void insert(MyList *list, int index, int num) { + assert(index < size(list)); + for (int i = size(list); i > index; --i) { + list->nums[i] = list->nums[i-1]; + } + list->nums[index] = num; + list->size++; +} + +/* 删除元素 */ +// 由于引入了 stdio.h ,此处无法使用 remove 关键词 +// 详见 https://github.com/krahets/hello-algo/pull/244#discussion_r1067863888 +int removeNum(MyList *list, int index) { + assert(index < size(list)); + int num = list->nums[index]; + for (int i = index; i < size(list) - 1; i++) { + list->nums[i] = list->nums[i+1]; + } + list->size--; + return num; +} + +/* 列表扩容 */ +void extendCapacity(MyList *list) { + // 先分配空间 + int newCapacity = capacity(list) * list->extendRatio; + int *extend = (int *)malloc(sizeof(int) * newCapacity); + int *temp = list->nums; + + // 拷贝旧数据到新数据 + for(int i = 0; i < size(list); i++) + extend[i] = list->nums[i]; + + // 释放旧数据 + free(temp); + + // 更新新数据 + list->nums = extend; + list->capacity = newCapacity; +} + +/* 将列表转换为 Array 用于打印 */ +int* toArray(MyList *list) { + return list->nums; +} + +int main() { + /* 初始化列表 */ + MyList list; + newMyList(&list); + /* 尾部添加元素 */ + add(&list, 1); + add(&list, 3); + add(&list, 2); + add(&list, 5); + add(&list, 4); + printf("列表 list = "); + printArray(toArray(&list), size(&list)); + printf("容量 = %d ,长度 = %d\r\n", capacity(&list), size(&list)); + + /* 中间插入元素 */ + insert(&list, 3, 6); + printf("在索引 3 处插入数字 6 ,得到 list = "); + printArray(toArray(&list), size(&list)); + + /* 删除元素 */ + removeNum(&list, 3); + printf("删除索引 3 处的元素,得到 list = "); + printArray(toArray(&list), size(&list)); + + /* 访问元素 */ + int num = get(&list, 1); + printf("访问索引 1 处的元素,得到 num = %d\r\n", num); + + /* 更新元素 */ + set(&list, 1, 0); + printf("将索引 1 处的元素更新为 0 ,得到 list = "); + printArray(toArray(&list), size(&list)); + + /* 测试扩容机制 */ + for (int i = 0; i < 10; i++) { + // 在 i = 5 时,列表长度将超出列表容量,此时触发扩容机制 + add(&list, i); + } + + printf("扩容后的列表 list = "); + printArray(toArray(&list), size(&list)); + printf("容量 = %d ,长度 = %d\r\n", capacity(&list), size(&list)); + + /* 析构函数,释放分配内存 */ + delMyList(&list); +} \ No newline at end of file diff --git a/codes/c/chapter_stack_and_queue/CMakeLists.txt b/codes/c/chapter_stack_and_queue/CMakeLists.txt new file mode 100644 index 000000000..5c2be36b6 --- /dev/null +++ b/codes/c/chapter_stack_and_queue/CMakeLists.txt @@ -0,0 +1,2 @@ +add_executable(array_stack array_stack.c) +add_executable(linkedlist_stack linkedlist_stack.c) \ No newline at end of file diff --git a/codes/c/chapter_stack_and_queue/array_stack.c b/codes/c/chapter_stack_and_queue/array_stack.c new file mode 100644 index 000000000..df7e08139 --- /dev/null +++ b/codes/c/chapter_stack_and_queue/array_stack.c @@ -0,0 +1,43 @@ +/** + * File: array_stack.c + * Created Time: 2022-01-12 + * Author: Zero (glj0@outlook.com) + */ + +#include "../include/include.h" + + +struct ArrayStack { + int *array; + size_t stkSize; +}; + +typedef struct ArrayStack ArrayStack; + +void new(ArrayStack* stk) { + +} + +size_t size(ArrayStack* stk) { + +} + +bool empty(ArrayStack* stk) { + +} + +void push(ArrayStack* stk, int num) { + +} + +void pop(ArrayStack* stk) { + +} + +int top(ArrayStack* stk) { + +} + +int main() { + return 0; +} \ No newline at end of file diff --git a/codes/c/chapter_stack_and_queue/linkedlist_stack.c b/codes/c/chapter_stack_and_queue/linkedlist_stack.c new file mode 100644 index 000000000..a63ea1919 --- /dev/null +++ b/codes/c/chapter_stack_and_queue/linkedlist_stack.c @@ -0,0 +1,110 @@ +/** + * File: linkedlist_stack.c + * Created Time: 2022-01-12 + * Author: Zero (glj0@outlook.com) + */ + +#include "../include/include.h" + +/* 基于链表实现的栈 */ +struct LinkedListStack { + ListNode* stackTop; // 将头结点作为栈顶 + int size; // 栈的长度 +}; + +typedef struct LinkedListStack LinkedListStack; + +/* 构造函数 */ +void newLinkedListStack(LinkedListStack* stk) { + stk->stackTop = NULL; + stk->size = 0; +} + +/* 析构函数 */ +void delLinkedListStack(LinkedListStack* stk) { + while(stk->stackTop) { + ListNode *n = stk->stackTop->next; + free(stk->stackTop); + stk->stackTop = n; + } + stk->size = 0; +} + +/* 获取栈的长度 */ +int size(LinkedListStack* stk) { + assert(stk); + return stk->size; +} + +/* 判断栈是否为空 */ +bool empty(LinkedListStack* stk) { + assert(stk); + return size(stk) == 0; +} + +/* 访问栈顶元素 */ +int top(LinkedListStack* stk) { + assert(stk); + assert(size(stk) != 0); + return stk->stackTop->val; +} + +/* 入栈 */ +void push(LinkedListStack* stk, int num) { + assert(stk); + ListNode *node = (ListNode *)malloc(sizeof(ListNode)); + node->next = stk->stackTop; // 更新新加结点指针域 + node->val = num; // 更新新加结点数据域 + stk->stackTop = node; // 更新栈顶 + stk->size++; // 更新栈大小 +} + +/* 出栈 */ +void pop(LinkedListStack* stk) { + assert(stk); + int num = top(stk); + ListNode *tmp = stk->stackTop; + stk->stackTop = stk->stackTop->next; + // 释放内存 + free(tmp); + stk->size--; +} + +/* Driver Code */ +int main() { + /* 初始化栈 */ + LinkedListStack stack; + /* 构造函数 */ + newLinkedListStack(&stack); + + /* 元素入栈 */ + push(&stack, 1); + push(&stack, 3); + push(&stack, 2); + push(&stack, 5); + push(&stack, 4); + + printf("栈 stack = "); + printLinkedList(stack.stackTop); + + /* 访问栈顶元素 */ + int stackTop = top(&stack); + printf("栈顶元素 top = %d\r\n", stackTop); + + /* 元素出栈 */ + pop(&stack); + printf("出栈元素 pop = %d, 出栈后 stack = ", stackTop); + printLinkedList(stack.stackTop); + + /* 获取栈的长度 */ + int stackSize = size(&stack); + printf("栈的长度 size = %d\r\n", stackSize); + + /* 判断是否为空 */ + bool isEmpty = empty(&stack); + printf("栈是否为空 = %s\r\n", isEmpty ? "yes" : "no"); + + /* 析构函数 */ + delLinkedListStack(&stack); + return 0; +} diff --git a/codes/c/include/include.h b/codes/c/include/include.h index 9f30b0529..e3919a9f5 100644 --- a/codes/c/include/include.h +++ b/codes/c/include/include.h @@ -12,6 +12,7 @@ #include #include #include +#include #include "list_node.h" #include "tree_node.h"