diff --git a/yonglin_zhang/CMakeLists.txt b/yonglin_zhang/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..dc9b184c4067c174b79572f4b608e89109a85ccb --- /dev/null +++ b/yonglin_zhang/CMakeLists.txt @@ -0,0 +1,6 @@ +cmake_minimum_required(VERSION 3.0) + +project(alg C) + +add_subdirectory(unit-testing) +add_subdirectory(link_list) \ No newline at end of file diff --git a/yonglin_zhang/include/alg_errno.h b/yonglin_zhang/include/alg_errno.h new file mode 100644 index 0000000000000000000000000000000000000000..55d4123c396dab10a977697aa67bb65945b2f378 --- /dev/null +++ b/yonglin_zhang/include/alg_errno.h @@ -0,0 +1,21 @@ +/** + * \brief 算法通用错误码 +*/ + +#ifndef ALG_ERRNO_H +#define ALG_ERRNO_H + +#ifdef __cplusplus +extern "C" { +#endif + +#define ALG_OK 0x0000 // 执行成功 +#define ALG_BAD_INPUT 0x0001 // 输入数据不合法 +#define ALG_MALLOC_FAIL 0x0002 // 内存空间不足 +#define ALG_NODE_NOT_EXIST 0x0003 // 目标节点不存在 + +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/yonglin_zhang/link_list/CMakeLists.txt b/yonglin_zhang/link_list/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..c6fc47481660cdeeec7a3b61e3a3da09c4313264 --- /dev/null +++ b/yonglin_zhang/link_list/CMakeLists.txt @@ -0,0 +1,5 @@ +set(LINK_SDK_NAME "link_list") +set(LINK_SDK_NAME_STATIC "link_list-static") + +add_subdirectory(src) +add_subdirectory(test) \ No newline at end of file diff --git a/yonglin_zhang/link_list/include/link_list.h b/yonglin_zhang/link_list/include/link_list.h new file mode 100644 index 0000000000000000000000000000000000000000..b6aef2f9f5bdd0ae50869823fdeaf68bc6f83489 --- /dev/null +++ b/yonglin_zhang/link_list/include/link_list.h @@ -0,0 +1,81 @@ +/** + * \file 链表头文件 +*/ + +#ifndef LINK_LIST_H +#define LINK_LIST_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include "alg_errno.h" + +typedef int data_type; +typedef struct _link_list link_list; + +/** + * \brief 句柄初始化 + * + * \warning ctx必须为二级指针,为了防止内存泄漏,请保证ctx为NULL + * + * \param ctx[out] 初始化句柄 + * + * \return \c ALG_OK 初始化成功 +*/ +int list_init(link_list **ctx); + +/** + * \brief 头部添加一个节点 + * + * \param ctx[in] 指针句柄 + * \param data[in] 待插入数据 + * + * \return \c ALG_OK 添加成功 +*/ +int list_add_head(link_list *ctx, data_type data); + +/** + * \brief 尾部添加一个节点 + * + * \param ctx[in] 指针句柄 + * \param data[in] 待插入数据 + * + * \return \c ALG_OK 添加成功 +*/ +int list_add_rear(link_list *ctx, data_type data); + +/** + * \brief 删除链表中第一个为target的元素 + * + * \param ctx[in] 指针句柄 + * \param target[in] 目标元素 + * + * \return \c ALG_OK 删除成功 +*/ +int list_delete_first_target(link_list *ctx, data_type target); + +/** + * \brief 清空链表中的元素 + * + * \param ctx[in] 指针句柄 + * + * \return \c ALG_OK 执行成功 +*/ +int list_clean(link_list *ctx); + +/** + * \brief 打印链表中的所有内容 + * + * \param ctx[in] 指针句柄 + * + * \return \c ALG_OK 打印完毕 +*/ +int list_show(link_list *ctx); + +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/yonglin_zhang/link_list/src/CMakeLists.txt b/yonglin_zhang/link_list/src/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..ab5fb40cfc206b2b0589de3a323d61649a39de2b --- /dev/null +++ b/yonglin_zhang/link_list/src/CMakeLists.txt @@ -0,0 +1,13 @@ +set(LIB_SRC + link_list.c +) + +set(INCLUDE_DIR + ${CMAKE_CURRENT_SOURCE_DIR}/../include + ${CMAKE_CURRENT_SOURCE_DIR}/../../include +) + +include_directories(${INCLUDE_DIR}) + +add_library(${LINK_SDK_NAME} SHARED ${LIB_SRC}) +add_library(${LINK_SDK_NAME_STATIC} STATIC ${LIB_SRC}) diff --git a/yonglin_zhang/link_list/src/link_list.c b/yonglin_zhang/link_list/src/link_list.c new file mode 100644 index 0000000000000000000000000000000000000000..be423081a2f980cbfba1d23c3e5d7ad6f19e01d4 --- /dev/null +++ b/yonglin_zhang/link_list/src/link_list.c @@ -0,0 +1,154 @@ +#include +#include +#include "link_list.h" +#include "alg_errno.h" + +struct _link_list{ + data_type data; + struct _link_list *next; +}; + +typedef struct _link_list node; + +/* 初始化句柄 */ +int list_init(link_list **ctx) +{ + if(ctx == NULL) { + return ALG_BAD_INPUT; + } + if(*ctx != NULL) { + return ALG_BAD_INPUT; + } + + *ctx = (node *)malloc(sizeof(node)); + + (*ctx)->data = 0; + (*ctx)->next = NULL; + + if(*ctx == NULL) { + return ALG_MALLOC_FAIL; + } + + return ALG_OK; +} + +/* 头部插入一个节点 */ +int list_add_head(link_list *ctx, data_type data) +{ + node *t = NULL; + + if(ctx == NULL) { + return ALG_BAD_INPUT; + } + + t = (node *)malloc(sizeof(node)); + t->data = data; + t->next = ctx->next; + + ctx->next = t; + + return ALG_OK; +} + +/* 尾部插入一个节点 */ +int list_add_rear(link_list *ctx, data_type data) +{ + node *t = NULL, *p = NULL; + + if(ctx == NULL) { + return ALG_BAD_INPUT; + } + + t = (node *)malloc(sizeof(node)); + if(t == NULL) { + return ALG_MALLOC_FAIL; + } + + t->next = NULL; + t->data = data; + + p = ctx; + while(p->next != NULL) { + p = p->next; + } + p->next = t; + + return ALG_OK; +} + +/* 删除第一个为target元素的节点 */ +int list_delete_first_target(link_list *ctx, data_type target) +{ + node *t = NULL; + + if(ctx == NULL) { + return ALG_BAD_INPUT; + } + + if(ctx->next == NULL) { + return ALG_BAD_INPUT; + } + + t = ctx; + while(t->next != NULL) { + if(t->next->data == target) { + node *temp = t->next; + t->next = temp->next; + free(t); + return ALG_OK; + } + t = t->next; + } + + return ALG_NODE_NOT_EXIST; +} + +/* 清空链表 */ +int list_clean(link_list *ctx) +{ + node *t = NULL; + + if(ctx == NULL) { + return ALG_BAD_INPUT; + } + + if(ctx->next == NULL) { + return ALG_OK; + } + + t = ctx->next; + while(t != NULL) { + node *temp = t; + t = t->next; + free(temp); + } + + ctx->next = NULL; + + return ALG_OK; +} + +/* 打印链表 */ +int list_show(link_list *ctx) +{ + node *t = NULL; + + if(ctx == NULL) { + return ALG_BAD_INPUT; + } + if(ctx->next == NULL) { + return ALG_BAD_INPUT; + } + + t = ctx->next; + + printf("%d", t->data); + t = t->next; + + while(t != NULL) { + printf("->%d", t->data); + t = t->next; + } + + return ALG_OK; +} \ No newline at end of file diff --git a/yonglin_zhang/link_list/test/CMakeLists.txt b/yonglin_zhang/link_list/test/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..1d4c16beeb060afef8ab7a695c08652dc4319bb4 --- /dev/null +++ b/yonglin_zhang/link_list/test/CMakeLists.txt @@ -0,0 +1,41 @@ +set(INCLUDE_DIRS + ${CMAKE_CURRENT_SOURCE_DIR}/. + ${CMAKE_CURRENT_SOURCE_DIR}/../include + ${CMAKE_CURRENT_SOURCE_DIR}/../../include + ${CMAKE_SOURCE_DIR}/build/unit-testing/ + ${CMAKE_SOURCE_DIR}/build/unit-testing/src/ +) + +set(DEP_LIBS + check + link_list + check_interface + pthread +) + +set(DEP_LIBS_DIR + ${CMAKE_SOURCE_DIR}/build/unit-testing/src/ + ${CMAKE_SOURCE_DIR}/build/link_list/src/ + ${CMAKE_SOURCE_DIR}/build/link_list/test/ +) + +set(SRC + check_add.c + check_init.c + check_clean.c + check_delete_first.c + check_interface.c +) + +set(TEST_LIB_NAME + check_interface +) + +link_directories(${DEP_LIBS_DIR}) +include_directories(${INCLUDE_DIRS}) + +add_library(${TEST_LIB_NAME} SHARED ${SRC}) +target_link_libraries(${TEST_LIB_NAME} link_list) + +add_executable(interface_test check_interface.c) +target_link_libraries(interface_test ${DEP_LIBS} check_interface) \ No newline at end of file diff --git a/yonglin_zhang/link_list/test/check_add.c b/yonglin_zhang/link_list/test/check_add.c new file mode 100644 index 0000000000000000000000000000000000000000..7edddea3ef7a7956aa310070ee23d77a9f5c8707 --- /dev/null +++ b/yonglin_zhang/link_list/test/check_add.c @@ -0,0 +1,41 @@ +#include + +#include "check_interface.h" +#include "link_list.h" +#include "alg_errno.h" + +START_TEST(test_ok) +{ + link_list *ctx = NULL; + + ck_assert_int_eq(list_init(&ctx), ALG_OK); + + ck_assert_int_eq(list_add_head(ctx, 10), ALG_OK); + ck_assert_int_eq(list_add_rear(ctx, 10), ALG_OK); +} +END_TEST + +START_TEST(test_not_init) +{ + link_list *ctx = NULL; + + ck_assert_int_eq(list_add_head(ctx, 10), ALG_BAD_INPUT); + ck_assert_int_eq(list_add_rear(ctx, 10), ALG_BAD_INPUT); +} +END_TEST + +Suite *check_add(void) +{ + Suite *s; + TCase *tc_core; + + s = suite_create("list_add test"); + + tc_core = tcase_create("core"); + tcase_add_test(tc_core, test_ok); + tcase_add_test(tc_core, test_not_init); + + suite_add_tcase(s, tc_core); + + return s; +} \ No newline at end of file diff --git a/yonglin_zhang/link_list/test/check_clean.c b/yonglin_zhang/link_list/test/check_clean.c new file mode 100644 index 0000000000000000000000000000000000000000..681f7444e909b0b44296b2d9d6623158950d001a --- /dev/null +++ b/yonglin_zhang/link_list/test/check_clean.c @@ -0,0 +1,41 @@ +#include + +#include "check_interface.h" +#include "link_list.h" +#include "alg_errno.h" + +START_TEST(test_init) +{ + link_list *ctx = NULL; + ck_assert_int_eq(list_init(&ctx), ALG_OK); + ck_assert_int_eq(list_add_head(ctx, 10), ALG_OK); + ck_assert_int_eq(list_clean(ctx), ALG_OK); + ck_assert_int_eq(list_clean(ctx), ALG_OK); +} +END_TEST + +START_TEST(test_input) +{ + link_list *ctx = NULL; + + ck_assert_int_eq(list_init(&ctx), ALG_OK); + ck_assert_int_eq(list_clean(NULL), ALG_BAD_INPUT); + ck_assert_int_eq(list_clean(ctx), ALG_OK); +} +END_TEST + +Suite *check_free(void) +{ + Suite *s; + TCase *tc_core; + + s = suite_create("list_clean test"); + + tc_core = tcase_create("core"); + tcase_add_test(tc_core, test_init); + tcase_add_test(tc_core, test_input); + + suite_add_tcase(s, tc_core); + + return s; +} \ No newline at end of file diff --git a/yonglin_zhang/link_list/test/check_delete_first.c b/yonglin_zhang/link_list/test/check_delete_first.c new file mode 100644 index 0000000000000000000000000000000000000000..53766b33e914695786447e3c85aab32617184f5d --- /dev/null +++ b/yonglin_zhang/link_list/test/check_delete_first.c @@ -0,0 +1,54 @@ +#include + +#include "check_interface.h" +#include "link_list.h" +#include "alg_errno.h" + +START_TEST(test_init) +{ + link_list *ctx = NULL; + ck_assert_int_eq(list_init(&ctx), ALG_OK); + ck_assert_int_eq(list_add_head(ctx, 10), ALG_OK); + ck_assert_int_eq(list_delete_first_target(ctx, 10), ALG_OK); +} +END_TEST + +START_TEST(test_input) +{ + link_list *ctx = NULL; + + //测试未初始化的指针和空指针 + ck_assert_int_eq(list_delete_first_target(ctx, 10), ALG_BAD_INPUT); + ck_assert_int_eq(list_delete_first_target(NULL, 10), ALG_BAD_INPUT); + + //测试初始化指针,但未添加任何元素 + ck_assert_int_eq(list_init(&ctx), ALG_OK); + ck_assert_int_eq(list_delete_first_target(ctx, 10), ALG_BAD_INPUT); +} +END_TEST + +START_TEST(test_not_exist) +{ + link_list *ctx = NULL; + ck_assert_int_eq(list_init(&ctx), ALG_OK); + ck_assert_int_eq(list_add_head(ctx, 10), ALG_OK); + ck_assert_int_eq(list_delete_first_target(ctx, 32), ALG_NODE_NOT_EXIST); +} +END_TEST + +Suite *check_delete(void) +{ + Suite *s; + TCase *tc_core; + + s = suite_create("list_delete test"); + + tc_core = tcase_create("core"); + tcase_add_test(tc_core, test_init); + tcase_add_test(tc_core, test_input); + tcase_add_test(tc_core, test_not_exist); + + suite_add_tcase(s, tc_core); + + return s; +} \ No newline at end of file diff --git a/yonglin_zhang/link_list/test/check_init.c b/yonglin_zhang/link_list/test/check_init.c new file mode 100644 index 0000000000000000000000000000000000000000..eeddd8c13fab85307ef7fd68e72c5a7ee02794ec --- /dev/null +++ b/yonglin_zhang/link_list/test/check_init.c @@ -0,0 +1,35 @@ +#include + +#include "check_interface.h" +#include "link_list.h" +#include "alg_errno.h" + +START_TEST(test_init) +{ + link_list *ctx = NULL; + ck_assert_int_eq(list_init(&ctx), ALG_OK); +} +END_TEST + +START_TEST(test_input) +{ + link_list *ctx = NULL; + ck_assert_int_eq(list_init(NULL), ALG_BAD_INPUT); +} +END_TEST + +Suite *check_init(void) +{ + Suite *s; + TCase *tc_core; + + s = suite_create("list_init test"); + + tc_core = tcase_create("core"); + tcase_add_test(tc_core, test_init); + tcase_add_test(tc_core, test_input); + + suite_add_tcase(s, tc_core); + + return s; +} \ No newline at end of file diff --git a/yonglin_zhang/link_list/test/check_interface.c b/yonglin_zhang/link_list/test/check_interface.c new file mode 100644 index 0000000000000000000000000000000000000000..069aae4e51cc5dd568d9660f825c5f33dead6e94 --- /dev/null +++ b/yonglin_zhang/link_list/test/check_interface.c @@ -0,0 +1,22 @@ +#include +#include "check_interface.h" + +int main() +{ + SRunner *sr; + int number_failed = 0; + + sr = srunner_create(check_init()); + srunner_add_suite(sr, check_add()); + srunner_add_suite(sr, check_delete()); + srunner_add_suite(sr, check_free()); + + /* can debug with gdb */ + srunner_set_fork_status(sr, CK_NOFORK); + + srunner_run_all (sr, CK_VERBOSE); + number_failed = srunner_ntests_failed(sr); + srunner_free(sr); + + return 0; +} \ No newline at end of file diff --git a/yonglin_zhang/link_list/test/check_interface.h b/yonglin_zhang/link_list/test/check_interface.h new file mode 100644 index 0000000000000000000000000000000000000000..a1621c713e899da5b009a30589355fcb8efe5f65 --- /dev/null +++ b/yonglin_zhang/link_list/test/check_interface.h @@ -0,0 +1,11 @@ +#ifndef CHECK_INTERFACE_H +#define CHECK_INTERFACE_H + +#include "check.h" + +Suite *check_init(void); +Suite *check_add(void); +Suite *check_delete(void); +Suite *check_free(void); + +#endif \ No newline at end of file