单链表管理(基于固定的链表结构)

作用:

        一定程度上免去每次需要用到链表结构时都需要重写增删查改这几个基础功能

当前进度:

        ver_1.0,能用,但不确定有没有bug

使用前置需求:

        链表结构体的第一个参数是指向下一节点指针(即*next),如下:

typedef struct LIST_STRUCT_NAME{
    struct STRUCT_NAME *next;    //指向下一位指针必须放在第一位
    //之后定义自身需要变量
    //**data
}list_st;

        需要一个头节点指针以及尾节点指针

typedef struct LIST_STRUCT_NAME{
    struct STRUCT_NAME *next;    //指向下一位指针必须放在第一位
    //之后定义自身需要变量
    //**data
}list_st;

list_st *head=NULL;
list_st *tail=NULL;

代码和解释:



/**
* 定义一个结构体用于操作链表
* 因为next指针都是第一个元素,所以其他结构体链表可以强转成这个统一操作
*/
typedef struct LIST_MANAGE_STRUCT {
    struct LIST_MANAGE_STRUCT* next;
}list_st;

/**
 * 链表扫描
 ** 此函数用于遍历从ihead节点开始,到尾节点或者回调函数返回1时结束
 ** 每遍历到一个链表节点,都会调用回调函数
 ** 当回调函数返回1时,扫描函数会停止继续扫描,且返回当前节点地址
 * void* ihead
 ** 头指针 (即head)
 * int task(void* arg, void *args)
 ** 回调函数
 * void *args
 ** 提供给会回调函数的参数(->args)
*/
/**
 * int task(void* arg, void *args):回调函数
 * void* arg: 遍历中的结构体指针
 * void *args:扫描链表中提供的参数
*/
void* list_scan(void* ihead, int task(void* arg, void *args), void *args) {
    list_st* ilist = (list_st*)ihead;
    while (ilist!=NULL){
        if (task(ilist, args))return ilist;
        ilist = ilist->next;
    }
    return NULL;
}
/**
 * 扫描函数回调函数
*/
int list_find_last_cb(void* arg, void *args) {
    if (((list_st*)arg)->next == (list_st*)args)return 1;
    return 0;
}
/**
 * 寻找index节点的上一个节点
 * index为头节点是,返回0xffffffff
 * 未找到节点,返回NULL
 * 寻找到节点,返回节点地址
*/
list_st* list_find_last(list_st* ihead, list_st* index) {
    if (ihead == index)return (list_st*)0xffffffff;
    return (list_st*)list_scan(ihead, list_find_last_cb, index);
}
/**
 * 添加一个节点到尾节点
 * void **head
 ** 头指针(即 &head)
 * void **tail
 ** 尾指针(即 &tail)
 * void *index
 ** 要添加的节点
*/
void list_add_tail(void **head, void **tail, void *index) {
    if (*(list_st**)head == NULL) {
        *(list_st**)head = (list_st*)index;
    }else {
        (*(list_st**)tail)->next = (list_st*)index;
    }
    *(list_st**)tail = (list_st*)index; 
    (*(list_st**)tail)->next = NULL;
}
/**
 * 删除节点
 * void **head
 ** 头指针(即 &head)
 * void **tail
 ** 尾指针(即 &tail)
 * void *index
 ** 要删除的节点
*/
void list_delete(void** head, void** tail, void* index) {
    list_st* p = NULL;
    if (*head == index) {
        *(list_st**)head = (*(list_st**)head)->next;
    }else {
        p = list_find_last(*(list_st**)head, (list_st*)index);
        if (p != NULL) {
            p->next = ((list_st*)index)->next;
            if (index == *tail) {
                *tail = p;
            }
        }
    }
}

//重定义函数,更方便使用
#define def_list_scan(head, task, args)         list_scan(head, task, args)
#define def_list_add_tail(head, tail, index)    list_add_tail((void**)&head, (void**)&tail, &index)
#define def_list_delete(head, tail, index)      list_delete((void**)&head, (void**)&tail, &index)

//拓展
/**
 * 在orign节点后插入index节点 
 * void **head
 ** 头指针(即 &head)
 * void *orign
 ** 目标节点
 * void *index
 ** 要插入的节点
*/
void list_insert_hou(void** tail, void* orign, void* index) {
    if (*tail == orign) {
        *tail = index;
    }
    ((list_st*)index)->next = ((list_st*)orign)->next;
    ((list_st*)orign)->next = (list_st*)index;
}
/**
 * 在orign节点前插入index节点 
 * void **head
 ** 头指针(即 &head)
 * void *orign
 ** 目标节点
 * void *index
 ** 要插入的节点
*/
void list_insert_qian(void** head, void* orign, void* index) {
    list_st* p = NULL;
    if (*head == orign) {
        ((list_st*)index)->next = (list_st*)orign;
        *head = index;
    }
    else {
        p = list_find_last((*(list_st**)head), (list_st*)orign);
        if (p != NULL) {
            p->next = (list_st*)index;
            ((list_st*)index)->next = (list_st*)orign;
        }
    }
}



//测试
/**
 * 测试链表结构体
*/
typedef struct TEST_LIST_MANAGE_STRUCT {
    struct TEST_LIST_MANAGE_STRUCT* next;
    int num;
}exp_st;
/**
 * 头指针,尾指针
*/
exp_st* exp_head = NULL;
exp_st* exp_tail = NULL;
//重定义添加函数
#define def_clist(iexp) list_add_tail((void**)&exp_head, (void**)&exp_tail, &iexp)
//打印节点变量,作为list_scan的回调函数
int exp_printf_list(void *arg, void *args) {
    printf("num:%d\n", ((exp_st*)arg)->num);
    return 0;
}

/**
 * 测试数据
*/
exp_st exp1 = { NULL, 1 };
exp_st exp3 = { NULL, 3 };
exp_st exp5 = { NULL, 5 };
exp_st exp6 = { NULL, 6 };
exp_st exp7 = { NULL, 7 };
exp_st exp8 = { NULL, 8 };
exp_st exp9 = { NULL, 9 };
int main() {
    printf("add::95768\n");
    def_clist(exp9);
    def_clist(exp5);
    def_clist(exp7);
    def_clist(exp6);
    def_clist(exp8);
    def_list_scan(exp_head, exp_printf_list, NULL);
    printf("del::789\n");
    def_list_delete(exp_head, exp_tail, exp7);
    def_list_delete(exp_head, exp_tail, exp8);
    def_list_delete(exp_head, exp_tail, exp9);
    def_list_scan(exp_head, exp_printf_list, NULL);
    printf("add::789\n");
    def_clist(exp7);
    def_clist(exp8);
    def_clist(exp9);
    def_list_scan(exp_head, exp_printf_list, NULL);
    printf("add::13\n"); 
    list_insert_hou( (void**)&exp_tail, &exp7, &exp1);
    list_insert_qian((void**)&exp_head, &exp7, &exp3);
    def_list_scan(exp_head, exp_printf_list, NULL);
}


测试结果:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值