From 6e367209cad974fdc4e20ddd2fabc6179d332bb6 Mon Sep 17 00:00:00 2001 From: wjf-hs Date: Thu, 20 Jun 2024 17:18:06 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=9E=E7=8E=B0=E4=BA=86list=E5=B8=B8?= =?UTF-8?q?=E7=94=A8=E7=9A=84=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- datastruct/list.c | 154 +++++++++++++++++++--- datastruct/list.h | 28 ++-- datastruct/list_test.c | 277 ++++++++++++++++++++++++++++++---------- datastruct/main.c | 4 +- datastruct/stack_test.c | 12 +- 5 files changed, 365 insertions(+), 110 deletions(-) diff --git a/datastruct/list.c b/datastruct/list.c index e863e35..28c5332 100644 --- a/datastruct/list.c +++ b/datastruct/list.c @@ -360,78 +360,190 @@ void list_test(void) #endif - -// kernel bool list_append(struct _list* self, void* obj) { + assert(self != NULL); + assert(self->obj != NULL); + assert(obj != NULL); + if (self->size(self) == self->_capacity) + { + int capacity = self->_capacity * self->_ratio; + void * obj_new = (list_data_t*)realloc(self->obj, capacity * self->_obj_size); + if (obj_new == NULL) + { + return false; + } + self->obj = obj_new; + self->_capacity = capacity; + } + uint32_t index = self->size(self); + uint32_t offset = index * self->_obj_size; + memmove((char*)self->obj + offset, obj, self->_obj_size); + + self->_size += 1; + return true; } bool list_clear(struct _list* self) { - + assert(self != NULL); + self->_size = 0; + return true; } bool list_empty(struct _list* self) { - + assert(self != NULL); + return !self->size(self); } uint32_t list_index(struct _list* self, void* obj) { - + return 0; } bool list_insert(struct _list* self, uint32_t index, void* obj) { + assert(index >= 0 && index < self->size(self)); + if (self->size(self) == self->_capacity) + { + int capacity = self->_capacity * self->_ratio; + void* obj_new = (list_data_t*)realloc(self->obj, capacity * self->_obj_size); + if (obj_new == NULL) + { + return false; + } + self->obj = obj_new; + self->_capacity = capacity; + } + uint32_t offset = index * self->_obj_size; + uint32_t offset1 = (index + 1) * self->_obj_size; + + memmove((char*)self->obj + offset, (char *)self->obj + offset, self->size(self) * self->_obj_size); + self->_size += 1; + return true; } -bool list_pop(struct _list* self, uint32_t index, void* obj) +bool list_pop(struct _list* self, int index, void* obj) { + assert(self != NULL); + assert(index >= (int)(0 - self->size(self)) && index < (int)self->size(self)); // list空的时候也会报错,太严格了有点 + if (self->empty(self)) + { + return false; + } + + if (index < 0) + { + index += self->size(self); + } + + uint32_t count = self->size(self) - 1 - index; + uint32_t offset = index * self->_obj_size; + uint32_t offset1 = (index + 1) * self->_obj_size; + if (obj != NULL) + { + memmove(obj, (char*)self->obj + offset, self->_obj_size); + } + memmove((char*)self->obj + offset, (char*)self->obj + offset1, count * self->_obj_size); + self->_size -= 1; + return true; } -bool list_at(struct _list* self, uint32_t index) +bool list_at(struct _list* self, int index, void *obj) { - + assert(self != NULL); + assert(obj != NULL); + assert(index >= (int)(0 - self->size(self)) && index < (int)self->size(self)); + + if (index < 0) + { + index += self->size(self); + } + uint32_t offset = index * self->_obj_size; + memmove(obj, (char*)self->obj + offset, self->_obj_size); + return true; } -bool list_set(struct _list* self, uint32_t index, void* obj) +bool list_set(struct _list* self, int index, void* obj) { - + assert(self != NULL); + assert(index >= (int)(0 - self->size(self)) && index < (int)self->size(self)); + if (index < 0) + { + index += self->size(self); + } + uint32_t offset = index * self->_obj_size; + memmove((char*)self->obj + offset, obj, self->_obj_size); + return true; } uint32_t list_size(struct _list* self) { - + return self->_size; } -bool list_remove(struct _list* self, uint32_t index) +bool list_remove(struct _list* self, int index) { + assert(self != NULL); + assert(index >= (int)(0 - self->size(self)) && index < (int)self->size(self)); + if (self->empty(self)) + { + return false; + } + + if (index < 0) + { + index += self->size(self); + } + + uint32_t count = self->size(self) - 1 - index; + uint32_t offset = index * self->_obj_size; + uint32_t offset1 = (index + 1) * self->_obj_size; + memmove((char*)self->obj + offset, (char*)self->obj + offset1, count * self->_obj_size); + self->_size -= 1; + return true; } bool list_reverse(struct _list* self) { - + return true; } bool list_sort(struct _list* self, uint8_t reserve, int (*compare)(void* obj, void* obj2)) { - + return true; } // free void list_destory(struct _list* self) { - + assert(self != NULL); + if (self->obj != NULL) + { + free(self->obj); + } } // print void list_print(struct _list* self) { + assert(self != NULL); + if (!self->empty(self)) + { + void* obj = NULL; + + for (uint32_t i = 0; i < self->size(self); i++) + { + obj = (char*)self->obj + i * self->_obj_size; + self->print_obj(obj); + } + } } bool list_init(struct _list* list, uint32_t obj_size) @@ -454,12 +566,12 @@ bool list_init(struct _list* list, uint32_t obj_size) list->index = list_index; list->insert = list_insert; list->pop = list_pop; - list->print = list->print; - list->remove = list->remove; - list->reverse = list->reverse; - list->set = list->set; - list->size = list->size; - list->sort = list->sort; + list->print = list_print; + list->remove = list_remove; + list->reverse = list_reverse; + list->set = list_set; + list->size = list_size; + list->sort = list_sort; // 3. set array list->obj = (void*)calloc(list->_capacity, list->_obj_size); diff --git a/datastruct/list.h b/datastruct/list.h index 3c01f2d..f4040d1 100644 --- a/datastruct/list.h +++ b/datastruct/list.h @@ -50,28 +50,22 @@ struct _list uint32_t _ratio; // 扩展比率 // kernel - bool (*append)(struct _list* self, void* obj); + bool (*append)(struct _list* self, void* obj); // 追加对象 + bool (*insert)(struct _list* self, uint32_t index, void* obj); // 在列表指定位置,插入对象 + bool (*pop)(struct _list* self, int index, void* obj); // 根据索引,删除对象并返回。 + bool (*remove)(struct _list* self, int index); // 根据索引,移除对象 + int (*index)(struct _list* self, void* obj); // 在列表中,查找数据是否存在,若存在则返回其索引。否则返回-1 + bool (*at)(struct _list* self, int index, void* obj); // 根据索引,获取对象 + bool (*set)(struct _list* self, int index, void* obj); // 根据索引,修改对象 + + // base + uint32_t(*size)(struct _list* self); bool (*clear)(struct _list* self); - bool (*empty)(struct _list* self); - uint32_t (*index)(struct _list* self, void* obj); - - bool (*insert)(struct _list* self, uint32_t index, void* obj); - - bool (*pop)(struct _list* self, uint32_t index, void* obj); - - bool (*at)(struct _list* self, uint32_t index); - - bool (*set)(struct _list* self, uint32_t index, void* obj); - - uint32_t(*size)(struct _list* self); - - bool (*remove)(struct _list* self, uint32_t index); - + // sort bool (*reverse)(struct _list* self); - bool (*sort)(struct _list* self, uint8_t reserve, int (*compare)(void* obj, void* obj2)); // free diff --git a/datastruct/list_test.c b/datastruct/list_test.c index 35f8ddd..3a3aba7 100644 --- a/datastruct/list_test.c +++ b/datastruct/list_test.c @@ -1,72 +1,221 @@ -#include "test.h" +#include "list.h" -#if LIST_TEST == 1 - -static void list_data_display(list_data_t data) +#if 0 +void list_test(void) { - printf("%d ", data); + int i = 0; + + list_data_t data = 0; + struct _list list; + list_init(&list); + + printf("----- append -----\n"); + for (i = 0; i < 18; i++) + { + list_append(&list, i); + list_print(&list); + } + + printf("----- delete -----\n"); + list_delete(&list, 17); + list_print(&list); + + list_delete(&list, 0); + list_print(&list); + + list_delete(&list, 9); + list_print(&list); + + printf("----- clear -----\n"); + list_clear(&list); + printf("----- insert -----\n"); + for (i = 0; i < 18; i++) + { + list_insert(&list, 0, i); + list_print(&list); + } + + printf("----- get -----\n"); + data = list_get(&list, 0); + printf("list[0] = %2d\n", data); + + data = list_get(&list, 17); + printf("list[17] = %2d\n", data); + + data = list_get(&list, 5); + printf("list[5] = %2d\n", data); + + printf("----- like python -----\n"); + data = list_get(&list, -1); + printf("list[-1] = %2d\n", data); + + data = list_get(&list, -5); + printf("list[-5] = %2d\n", data); + + data = list_get(&list, -18); + printf("list[-18] = %2d\n", data); + + printf("----- set -----\n"); + for (i = 0; i < 18; i++) + { + list_set(&list, i, i); + list_print(&list); + } + + list_print(&list); + list_destory(&list); } +#endif + +static void print_num(void* obj) +{ + printf("(%2d )", *(int*)obj); +} + +static void list_test_num(void) +{ + int i = 0; + int data[] = { 1,2,3,4,5,6,7,8,9,10 }; + int temp = 0; + int index = 0; + int len = sizeof(data) / sizeof(data[0]); + + struct _list list; + list_init(&list, sizeof(int)); + list.print_obj = print_num; + + printf("\n\n----- list_test_num -----\n"); + printf("----- push -----\n"); + for (i = 0; i < len; i++) + { + list.append(&list, &data[i]); + } + printf("----- print -----\n"); + list.print(&list); + printf("\n"); + + printf("----- remove -----\n"); + list.remove(&list, 9); + list.print(&list); + printf("\n"); + + list.remove(&list, 0); + list.print(&list); + printf("\n"); + + list.remove(&list, 4); + list.print(&list); + printf("\n"); + + printf("----- clear -----\n"); + list.clear(&list); + list.print(&list); + printf("\n"); + + printf("----- push -----\n"); + for (i = 0; i < len; i++) + { + list.append(&list, &data[i]); + } + printf("----- print -----\n"); + list.print(&list); + printf("\n"); + + printf("----- at -----\n"); + index = 0; + list.at(&list, index, &temp); + printf("list[%2d] = %2d\n", index, temp); + + index = 4; + list.at(&list, index, &temp); + printf("list[%2d] = %2d\n", index, temp); + + index = 9; + list.at(&list, index, &temp); + printf("list[%2d] = %2d\n", index, temp); + + + printf("----- set -----\n"); + index = 0; + temp = 11; + list.set(&list, index, &temp); + printf("list[%2d] = %2d\n", index, temp); + + index = 4; + temp = 22; + list.set(&list, index, &temp); + printf("list[%2d] = %2d\n", index, temp); + + index = 9; + temp = 33; + list.set(&list, index, &temp); + printf("list[%2d] = %2d\n", index, temp); + + printf("----- print -----\n"); + list.print(&list); + printf("\n"); + + + printf("----- at like python -----\n"); + index = -1; + list.at(&list, index, &temp); + printf("list[%2d] = %2d\n", index, temp); + + index = -6; + list.at(&list, index, &temp); + printf("list[%2d] = %2d\n", index, temp); + + index = -10; + list.at(&list, index, &temp); + printf("list[%2d] = %2d\n", index, temp); + + printf("----- set like python -----\n"); + index = -1; + temp = 99; + list.set(&list, index, &temp); + printf("list[%2d] = %2d\n", index, temp); + + index = -6; + temp = 98; + list.set(&list, index, &temp); + printf("list[%2d] = %2d\n", index, temp); + + index = -10; + temp = 97; + list.set(&list, index, &temp); + printf("list[%2d] = %2d\n", index, temp); + + printf("----- print -----\n"); + list.print(&list); + printf("\n"); + + printf("----- pop -----\n"); + for (i = 0; i < len + 1; i++) + { + if (true == list.pop(&list, 0, &temp)) + { + printf("top = "); + list.print_obj(&temp); + printf("\tsize after push = %2d\n", list.size(&list)); + } + else + { + printf("pop failed! because stack is empty\n"); + } + + if (list.empty(&list)) + { + printf("----- empty -----\n"); + break; + } + } + + list.destory(&list); +} + void list_test(void) { - int32_t i = 0; - list_data_t dat[10] = { 0,1,2,3,4,5,6,7,8,9 }; - plist_t list; - if (!list_init(&list)) - { - printf("list_init failureed!\n"); - } - printf("list_init success!\n"); - if (!list_empty(list)) - { - printf("list is empty!\n"); - } - for (i = 0; i < 10; i++) - { - list_insert_tail(list, dat[i]); - } - list_traversal_sequence(list, list_data_display); - printf("\nlist_traversal_sequence success!\n"); - list_traversal_reversed(list, list_data_display); - printf("\nlist_traversal_reversed success!\n"); - if (list_empty(list)) - { - printf("list is not empty!\n"); - } - - list_clear(list); - printf("list_clear success\n"); - for (i = 0; i < 10; i++) - { - list_insert_head(list, dat[i]); - } - if (!list_delete(list, 5)) - { - printf("list_delete failureed!\n"); - } - printf("list_delete success! Data5 has been deleted\n"); - printf("list_count = %d\n", list_count(list)); - - list_traversal_sequence(list, list_data_display); - printf("\nlist_traversal_sequence success!\n"); - list_traversal_reversed(list, list_data_display); - printf("\nlist_traversal_reversed success!\n"); - - list_destroy(&list); - printf("list_destroy success\n"); - - if (!list_insert_tail(list, dat[0])) - { - printf("list_insert_tail success\n"); - } - if (!list_insert_head(list, dat[0])) - { - printf("list_insert_head success\n"); - } - - printf("----------------------------------------\n"); + list_test_num(); } - -#endif - diff --git a/datastruct/main.c b/datastruct/main.c index 398e5bb..a94f567 100644 --- a/datastruct/main.c +++ b/datastruct/main.c @@ -5,8 +5,8 @@ int main() { // while (1) { - // list_test(); - stack_test(); + list_test(); + // stack_test(); // queue_test(); // tree_test(); // rbtree_test(); diff --git a/datastruct/stack_test.c b/datastruct/stack_test.c index a4614ba..7b4a1af 100644 --- a/datastruct/stack_test.c +++ b/datastruct/stack_test.c @@ -1,11 +1,11 @@ #include "stack.h" -void print_num(void* obj) +static void print_num(void* obj) { printf("(%2d )", *(int*)obj); } -void stack_test_num(void) +static void stack_test_num(void) { uint32_t i = 0; int data[] = { 1,2,3,4,5,6,7,8,9,10 }; @@ -58,12 +58,12 @@ void stack_test_num(void) s.destory(&s); } -void print_char(void* obj) +static void print_char(void* obj) { printf("(%2c )", *(char*)obj); } -void stack_test_char(void) +static void stack_test_char(void) { uint32_t i = 0; char data[] = "abcdefghijk"; @@ -122,13 +122,13 @@ struct _student int id; }; -void print_struct(void* obj) +static void print_struct(void* obj) { struct _student* student = (struct _student*)obj; printf("(%2d:%-5s ) ", student->id, student->name); } -void stack_test_struct(void) +static void stack_test_struct(void) { uint32_t i = 0; struct _student data[] = {