diff --git a/codes/c/chapter_array_and_linkedlist/list.c b/codes/c/chapter_array_and_linkedlist/list.c deleted file mode 100644 index 52deb1e1..00000000 --- a/codes/c/chapter_array_and_linkedlist/list.c +++ /dev/null @@ -1,206 +0,0 @@ -/** - * File: list.c - * Created Time: 2022-01-12 - * Author: Zero (glj0@outlook.com) - */ - -#include "../include/include.h" - - -#define MAX_ELEM_SIZE 10 -#define CAPACITY_RACTOR 2 - -// 用数组实现 list -struct list { - int* nums; - size_t cap; - size_t size; - bool isInit; -}; - -typedef struct list List; - -void listInit(List* l) { - if (l->isInit != true) { - l->cap = MAX_ELEM_SIZE; - l->nums = malloc(sizeof(int) * l->cap); - l->size = 0; - l->isInit = true; - } -} - -void listInitWithCapacity(List* l, size_t newCapacity) { - if (l->isInit != true) { - l->cap = newCapacity; - l->nums = malloc(sizeof(int) * l->cap); - l->size = 0; - l->isInit = true; - } -} - -size_t listSize(List* l) { - return l->size; -} - -size_t listCapacity(List* l) { - return l->cap; -} - -int listGet(List* l, int idx) { - assert(l->isInit); - if (l->isInit) { - if (idx < l->size) { - return l->nums[idx]; - } else { - - } - } - -} - -void listSet(List* l, int idx, int elem) { - assert(l->isInit); - if (l->isInit) { - if (idx < l->size) { - l->nums[idx] = elem; - } - } - assert("listSet elem assert."); -} - -void listExtendCapacity(List* l) { - // 先分配空间 - size_t newCapacity = listCapacity(l) * CAPACITY_RACTOR; - int *newData = (int *)malloc(sizeof(int) * newCapacity); - int *oldData = l->nums; - - // 拷贝旧数据到新数据 - for(size_t i=0; inums[i]; - - // 释放旧数据 - free(oldData); - - // 更新新数据 - l->nums = newData; - l->cap = newCapacity; -} - -void listAdd(List* l, int elem) { - if (listSize(l) == listCapacity(l)) { - listExtendCapacity(l); // 扩容 - } - l->nums[listSize(l)] = elem; - l->size ++; -} - -void listInsert(List* l, size_t idx, int elem) { - if (l->isInit) { - if (idx < listSize(l)) { - for (size_t i=listSize(l); i>idx; --i) { - l->nums[i] = l->nums[i-1]; - } - l->nums[idx] = elem; - l->size++; - } else { - // 越界 -- 抛出异常 - } - } else { - // 抛出异常 - } -} - -int listRemove(List* l, int idx) { - if (l->isInit) { - if (idx < listSize(l)) { - size_t i = idx; - if ( i != listSize(l)-1) { - for (; inums[i] = l->nums[i+1]; - } - } - l->size--; - - } else { - // 数组越界 - } - } else { - // 抛出异常 - } -} - -void listClear(List* l) { - l->size = 0; -} - -void printList(List* l) { - size_t i=0; - - printf("["); - if (l->size) { - for (; isize-1; i++) { - printf("%d, ", l->nums[i]); - } - printf("%d", l->nums[i]); - } - printf("]\r\n"); -} - -int main() { - List list; - /* 初始化列表 */ - listInit(&list); - listAdd(&list, 1); - listAdd(&list, 3); - listAdd(&list, 2); - listAdd(&list, 5); - listAdd(&list, 4); - - printf("列表 list = "); - printList(&list); - - - /* 访问元素 */ - int num = listGet(&list, 1); - printf("访问索引 1 处的元素,得到 num = %d\r\n", num); - - /* 更新元素 */ - listSet(&list, 1, 0); - printf("将索引 1 处的元素更新为 0 ,得到 list = "); - printList(&list); - - /* 清空列表 */ - listClear(&list); - printf("清空列表后 list = "); - printList(&list); - - /* 尾部添加元素 */ - listAdd(&list, 1); - listAdd(&list, 3); - listAdd(&list, 2); - listAdd(&list, 5); - listAdd(&list, 4); - printf("添加元素后 list = "); - printList(&list); - - /* 中间插入元素 */ - listInsert(&list, 3, 6); - printf("在索引 3 处插入数字 6 ,得到 list = "); - printList(&list); - - /* 删除元素 */ - listRemove(&list, 3); - printf("删除索引 3 处的元素,得到 list = "); - printList(&list); - - /* 尾部添加元素 */ - listAdd(&list, 1); - listAdd(&list, 3); - listAdd(&list, 2); - listAdd(&list, 5); - listAdd(&list, 4); - listAdd(&list, 4); - - printf("添加元素后 list = "); - printList(&list); -} \ 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 00000000..4f530b6e --- /dev/null +++ b/codes/c/chapter_array_and_linkedlist/my_list.c @@ -0,0 +1,154 @@ +/** + * 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* l); + +/* 构造函数 */ +void constructor(MyList* l) { + l->capacity = 10; + l->nums = malloc(sizeof(int) * l->capacity); + l->size = 0; + l->extendRatio = 2; +} + +/* 获取列表长度 */ +int size(MyList* l) { + return l->size; +} +/* 获取列表容量 */ +int capacity(MyList* l) { + return l->capacity; +} +/* 访问元素 */ +int get(MyList* l, int idx) { + if (idx < l->size) { + return l->nums[idx]; + } else { + + } +} +/* 更新元素 */ +void set(MyList* l, int idx, int elem) { + if (idx < l->size) { + l->nums[idx] = elem; + } +} +/* 尾部添加元素 */ +void add(MyList* l, int elem) { + if (size(l) == capacity(l)) { + extendCapacity(l); // 扩容 + } + l->nums[size(l)] = elem; + l->size ++; +} +/* 中间插入元素 */ +void insert(MyList* l, int idx, int elem) { + if (idx < size(l)) { + for (int i=size(l); i>idx; --i) { + l->nums[i] = l->nums[i-1]; + } + l->nums[idx] = elem; + l->size++; + } else { + // 越界:异常处理 + } +} +/* 删除元素 */ +// 由于引入了 stdio.h ,此处无法使用 remove 关键词 +// 详见 https://github.com/krahets/hello-algo/pull/244#discussion_r1067863888 +int removeNum(MyList* l, int idx) { + if (idx < size(l)) { + size_t i = idx; + if ( i != size(l)-1) { + for (; inums[i] = l->nums[i+1]; + } + } + l->size--; + } else { + // 数组越界 + } +} +/* 列表扩容 */ +void extendCapacity(MyList* l) { + // 先分配空间 + size_t newCapacity = capacity(l) * l->extendRatio; + int *extend = (int *)malloc(sizeof(int) * newCapacity); + int *temp = l->nums; + + // 拷贝旧数据到新数据 + for(size_t i=0; inums[i]; + + // 释放旧数据 + free(temp); + + // 更新新数据 + l->nums = extend; + l->capacity = newCapacity; +} + +/* 将列表转换为 Array 用于打印 */ +int* toArray(MyList* l) { + return l->nums; +} + +int main() { + /* 初始化列表 */ + MyList list; + constructor(&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)); +} \ No newline at end of file