JiXieShi 2024-06-21 13:25:01 +08:00
parent 60e82d529a
commit ef79633f1a
9 changed files with 650 additions and 7 deletions

10
demo/list/t_list.h Normal file
View File

@ -0,0 +1,10 @@
//
// Created by lydxh on 24-6-21.
//
#ifndef HW_LIB_T_LIST_H
#define HW_LIB_T_LIST_H
extern void Test_List();
#endif //HW_LIB_T_LIST_H

103
demo/list/test.c Normal file
View File

@ -0,0 +1,103 @@
#include <stdio.h>
#include "list.h"
typedef struct test {
int val1;
float val2;
} test_t;
void handle(void *data) {
test_t *test = (test_t *) data;
printf("val1:%d, val2:%f\n", test->val1, test->val2);
}
int compare_int(const void *s1, const void *s2) {
test_t *data1 = (test_t *) s1;
int *data2 = (int *) s2;
return (data1->val1 - *data2);
}
int compare_int_sort(const void *s1, const void *s2) {
test_t *data1 = (test_t *) s1;
test_t *data2 = (test_t *) s2;
return (data1->val1 - data2->val1);
}
void print(List *list) {
printf("list len = %ld\n", list_get_lenth(list));
if (!list_is_empty(list)) {
//test list_reverse
list_traverse(list, handle);
} else {
printf("\tthe list is empty\n");
}
}
void Test_List() {
List list;
list_init(&list);
test_t test1 = {10, 10.5};
test_t test2 = {20, 20.5};
test_t test3 = {30, 30.5};
test_t test4 = {40, 40.5};
test_t test5 = {50, 50.5};
//test list_insert
printf("------insert(_at_tail)----\n");
list_insert(&list, &test1);
list_insert(&list, &test2);
list_insert(&list, &test3);
print(&list);
//test list_delete
printf("------delete----\n");
list_delete(&list, &test1.val1, compare_int);
print(&list);
//test list_insert_at_head
printf("------insert_at_head----\n");
list_insert_at_head(&list, &test4);
print(&list);
//test list_insert_at_index
printf("------insert_at_index(2)----\n");
list_insert_at_index(&list, &test5, 2);
print(&list);
//test list_reverse
printf("------reverse----\n");
list_reverse(&list);
print(&list);
//test list_search
int key = 20;
test_t *ret;
printf("------search----\n");
ret = list_search(&list, &key, compare_int);
printf("%d:%f\n", ret->val1, ret->val2);
key = 50;
ret = list_search(&list, &key, compare_int);
printf("%d:%f\n", ret->val1, ret->val2);
//test list_get_element
printf("------list_get_element----\n");
ret = list_get_element(&list, 2);
printf("%d:%f\n", ret->val1, ret->val2);
ret = list_get_element(&list, 3);
printf("%d:%f\n", ret->val1, ret->val2);
//test list_sort
printf("-----sort----\n");
list_sort(&list, compare_int_sort);
print(&list);
//test list_destroy
printf("-----destroy----\n");
list_destroy(&list, NULL);
return 0;
}

View File

@ -5,6 +5,6 @@
#ifndef HW_LIB_T_TASK_H
#define HW_LIB_T_TASK_H
void Test_task();
_Noreturn void Test_task();
#endif //HW_LIB_T_TASK_H

32
lib/inc/list/array.h Normal file
View File

@ -0,0 +1,32 @@
#ifndef HW_LIB_ARRAY_H
#define HW_LIB_ARRAY_H
#ifdef __cplusplus
extern "C" {
#endif
// 在数组的索引 index 处插入元素 num
// nums: 操作数组
// size: 数组大小
// num: 操作数
// index: 操作位置
void insert(int *nums, int size, int num, int index);
// 删除索引 index 处的元素
// nums: 操作数组
// size: 数组大小
// index: 索引位置
// 注意stdio.h 占用了 remove 关键词
void removeItem(int *nums, int size, int index);
// 在数组中查找指定元素
// nums: 操作数组
// size: 数组大小
// target: 查找元素
int find(int *nums, int size, int target);
/* 扩展数组长度 */
int *extend(int *nums, int size, int enlarge);
#ifdef __cplusplus
}
#endif
#endif //HW_LIB_ARRAY_H

148
lib/inc/list/list.h Normal file
View File

@ -0,0 +1,148 @@
#ifndef HW_LIB_LIST_H
#define HW_LIB_LIST_H
#ifdef __cplusplus
extern "C" {
#endif
#include <stdbool.h>
typedef struct node { //节点结构
void *data;
struct node *next;
} node;
typedef struct { //链表结构
struct node *head;
struct node *tail;
long len;
} List;
/**
* @brief
* @param list: []
* @return void
* @example list_init(&myList);
*/
extern void list_init(List *list);
/**
* @brief
* @param list: []
* @return bool truefalse
* @example if (list_is_empty(&myList)) { // do something }
*/
extern bool list_is_empty(List *list);
/**
* @brief
* @param list: []
* @param data: []
* @return void
* @example list_insert(&myList, newData);
*/
extern void list_insert(List *list, void *data);
/**
* @brief
* @param list: []
* @param data: []
* @return void
* @example list_insert_at_head(&myList, newData);
*/
extern void list_insert_at_head(List *list, void *data);
/**
* @brief
* @param list: []
* @param data: []
* @return void
* @example list_insert_at_tail(&myList, newData);
*/
extern void list_insert_at_tail(List *list, void *data);
/**
* @brief
* @param list: []
* @param data: []
* @param idx: []
* @return void
* @example list_insert_at_index(&myList, newData, 2);
*/
extern void list_insert_at_index(List *list, void *data, long idx);
/**
* @brief
* @param list: []
* @param key: []
* @param compare: []
* @return void* NULL
* @example deletedData = list_delete(&myList, keyData, compareFunc);
*/
extern void *list_delete(List *list, void *key, int (*compare)(const void *, const void *));
/**
* @brief
* @param list: []
* @param key: []
* @param compare: []
* @return void* NULL
* @example foundData = list_search(&myList, keyData, compareFunc);
*/
extern void *list_search(List *list, void *key, int (*compare)(const void *, const void *));
/**
* @brief
* @param list: []
* @param compare: []
* @return void
* @example list_sort(&myList, compareFunc);
*/
extern void list_sort(List *list, int (*compare)(const void *, const void *));
/**
* @brief
* @param list: []
* @param handle: []
* @return void
* @example list_traverse(&myList, handleFunc);
*/
extern void list_traverse(List *list, void (*handle)(void *));
/**
* @brief
* @param list: []
* @return void
* @example list_reverse(&myList);
*/
extern void list_reverse(List *list);
/**
* @brief
* @param list: []
* @return long
* @example length = list_get_lenth(&myList);
*/
extern long list_get_lenth(List *list);
/**
* @brief
* @param list: []
* @param idx: []
* @return void* NULL
* @example element = list_get_element(&myList, 3);
*/
extern void *list_get_element(List *list, int idx);
/**
* @brief
* @param list: []
* @param destroy: []
* @return void
* @example list_destroy(&myList, destroyFunc);
*/
extern void list_destroy(List *list, void (*destroy)(void *data));
#ifdef __cplusplus
}
#endif
#endif //HW_LIB_LIST_H

View File

@ -44,9 +44,29 @@ typedef enum { // 定义枚举类型Type_t包含不同数据类型
#define TYPE_T(v) _Generic((v), \
u8 *:0,u16 *:1,u32 *:2, \
char *:3,short *:4,int *:5, \
float *:6,double *:10, \
float *:6,double *:7, \
default: ((void)0))
#define MESSAGE(err) \
( err==ERROR_NO_MEMORY ? MSG_NO_MEMORY \
: err==ERROR_INVALID_INDEX ? MSG_INVALID_INDEX \
: err==ERROR_INVALID_VALUE ? MSG_INVALID_VALUE \
: 0 )
#define TYPE_U8 (unsigned char *)
#define TYPE_ptr(type) \
(type==0 ? TYPE_U8 \
: type==1 ? (unsigned short *) \
: type==2 ? (unsigned int *) \
: type==3 ? (char *) \
: type==4 ? (short *) \
: type==5 ? (int *) \
: type==6 ? (float *) \
: type==7 ? (double *) \
: ((void)0))\
#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof(arr[0])) // 计算数组的元素个数
#define in , // 定义逗号为in

43
lib/src/list/array.cpp Normal file
View File

@ -0,0 +1,43 @@
#include <cstdlib>
#include "array.h"
void insert(int *nums, int size, int num, int index) {
// 把索引 index 以及之后的所有元素向后移动一位
for (int i = size - 1; i > index; i--) {
nums[i] = nums[i - 1];
}
// 将 num 赋给 index 处的元素
nums[index] = num;
}
void removeItem(int *nums, int size, int index) {
// 把索引 index 之后的所有元素向前移动一位
for (int i = index; i < size - 1; i++) {
nums[i] = nums[i + 1];
}
}
int find(int *nums, int size, int target) {
for (int i = 0; i < size; i++) {
if (nums[i] == target)
return i;
}
return -1;
}
/* 扩展数组长度 */
int *extend(int *nums, int size, int enlarge) {
// 初始化一个扩展长度后的数组
int *res = (int *) malloc(sizeof(int) * (size + enlarge));
// 将原数组中的所有元素复制到新数组
for (int i = 0; i < size; i++) {
res[i] = nums[i];
}
// 初始化扩展后的空间
for (int i = size; i < size + enlarge; i++) {
res[i] = 0;
}
// 返回扩展后的新数组
return res;
}

285
lib/src/list/list.cpp Normal file
View File

@ -0,0 +1,285 @@
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include "list.h"
void list_init(List *list) {
list->head = NULL;
list->tail = NULL;
list->len = 0;
}
bool list_is_empty(List *list) {
return (list->head == NULL);
}
static struct node *make_node(void *data) //把用户传递过来的数据打包为一个链表节点
{
struct node *n;
n = (struct node *) malloc(sizeof(struct node));
assert(n != NULL);
n->next = NULL;
n->data = data;
return n;
}
void list_insert_at_head(List *list, void *data) //头插法
{
struct node *n;
n = make_node(data);
if (list->head == NULL) { //如果是空链表
list->head = n;
list->tail = n;
} else { //如果不是非空链表
n->next = list->head;
list->head = n;
}
list->len++;
}
void list_insert_at_index(List *list, void *data, long index) //定插法
{
long i = 1; //从1开始算
struct node *p, *n;
p = list->head;
while (p && i < index) {
p = p->next;
i++;
}
if (p) { //如果链表遍历完了计数i还没到index说明第index个节点不存在。
n = make_node(data);
n->next = p->next;
p->next = n;
list->len++;
}
}
void list_insert_at_tail(List *list, void *data) //尾插法
{
struct node *n;
n = make_node(data);
if (list_is_empty(list)) { //如果是空链表
list->head = n;
list->tail = n;
} else { //如果不是非空链表
list->tail->next = n;
list->tail = n;
}
list->len++;
}
//void list_insert(List *list, void *data) //默认采用尾插法
//{
//#if 0
// list_insert_at_tail(list, data);
//#else
// struct node *n;
// n = make_node(data);
// if(list->head == NULL){
// list->head = n;
// list->tail = n;
// } else {
// list->tail->next = n;
// list->tail = n;
// }
// list->len++;
//#endif
//}
void list_insert(List *list, void *data) {
struct node *n;
n = make_node(data);
if (list->head == NULL) {
list->head = n;
list->tail = n;
} else {
list->tail->next = n;
list->tail = n;
}
list->len++;
}
void *list_delete(List *list, void *key, int (*compare)(const void *, const void *)) {
void *data;
struct node *n, *t;
n = list->head;
if (!compare(n->data, key)) { //如果要删除的节点为首节点
t = n;
data = n->data;
list->head = n->next;
free(t);
list->len--;
return data;
}
while (n->next != NULL) { //遍历查找符合条件的节点,删除之
if (compare(n->next->data, key) == 0) { //只删除第一个符合条件的节点。
t = n->next;
if (n->next == list->tail) {
list->tail = n;
}
n->next = n->next->next;
data = t->data;
free(t);
list->len--;
return data; //把删除的数据返回给用户,供用户后续的处理使用。
}
n = n->next;
}
return NULL; //没找到匹配的节点返回NULL
}
void *list_search(List *list, void *key, int (*compare)(const void *, const void *)) {
struct node *n;
n = list->head;
while (n) {
if (!compare(n->data, key)) { //找到了,返回找到的数据
return n->data;
}
n = n->next;
}
return NULL; //找不到返回NULL
}
static struct node *find_min_node(List *list,
int (*compare)(const void *, const void *)) {
struct node *min, *n;
n = list->head;
min = list->head;
while (n) {
if (compare(min->data, n->data) > 0) {
min = n;
}
n = n->next;
}
return min;
}
static void delete_node(List *list, struct node *key) {
struct node *n;
n = list->head;
if (n == key) {
list->head = n->next;
return;
}
while (n->next) {
if (n->next == key) {
if (key == list->tail) {
list->tail = n;
}
n->next = n->next->next;
return;
}
n = n->next;
}
}
static void insert_node(List *list, struct node *key) {
if (list->head == NULL) {
list->head = key;
list->tail = key;
} else {
list->tail->next = key;
list->tail = key;
}
}
void list_sort(List *list,
int (*compare)(const void *, const void *)) {
List tmp;
struct node *n;
list_init(&tmp);
while (!list_is_empty(list)) {
n = find_min_node(list, compare);
delete_node(list, n);
n->next = NULL;
insert_node(&tmp, n);
}
list->head = tmp.head;
list->tail = tmp.tail;
}
void list_traverse(List *list, void (*handle)(void *)) {
struct node *p;
p = list->head;
while (p) {
handle(p->data);
p = p->next;
}
}
void list_reverse(List *list) {
struct node *pre = NULL, *next, *p = list->head;
list->tail = list->head; //tail指向head
while (p) {
next = p->next;
if (!next) { //当p->next为最后一个节点时让head指向p->next
list->head = p;
}
//记录当前节点为pre作为下一个节点的next.第一个节点为NULL初始化时已定义。
p->next = pre;
pre = p;
p = next;
}
}
long list_get_lenth(List *list) {
return (list->len);
}
void *list_get_element(List *list, int idx) {
int i = 1;
struct node *n;
n = list->head;
while (n && i < idx) {
i++;
n = n->next;
}
if (n) {
return n->data;
}
return NULL;
}
void list_destroy(List *list, void (*destroy)(void *)) {
list->len = 0;
struct node *n, *t;
n = list->head;
while (n) {
t = n->next; //t只起一个记录n->next的功能否则后面把n free掉之后就找不到n->next了。
if (destroy) { //传递用户自定义的数据处理函数为0时不执行
destroy(n->data); //使用用户提供的destroy函数来释放用户传递过来的数据。
}
free(n);
n = t; //把n free掉之后再把t给n相当于把n->next给n,如此循环遍历链表,挨个删除,
}
}

12
main.c
View File

@ -5,6 +5,7 @@
#include "t_iic.h"
#include "t_task.h"
#include "t_arg.h"
#include "t_list.h"
#include "tool.h"
#include <time.h>
@ -12,14 +13,15 @@
int main() {
srand((unsigned) time(NULL));
int i = 1;
POUT((++i) + (++i));
// POUT((++i) + (++i));
char str[] = "123.456";
float result = Str2Float(str);
printf("Result: %.3f\n", result);
Test_RunTime("SPI", Test_spi);
// char str[] = "123.456";
// float result = Str2Float(str);
// printf("Result: %.3f\n", result);
// Test_RunTime("SPI", Test_spi);
// Test_RunTime("IIC", Test_iic);
// Test_RunTime("ArgPase", Test_argpase);
// Test_RunTime("Task", Test_task);
Test_RunTime("List", Test_List);
return 0;
}