C语言学习笔记(9){通用双向链表}

main.c

#include <stdio.h>
#include <stdlib.h>
#include "list2222.h"
static void print_ss(const void *record) //回调这个
{
    const struct score_st *r = record;
    
    printf("%d,%s,%d,%d\n",r->id,r->name,r->math,r->chinese);
}
static int id_cmp(const void *key,const void *record)
{
    const int *k = key;
    const struct score_st *r = record;

    return(*k - r->id);
}
int main()
{
    LLIST *handler;
    struct score_st tmp;
    
    handler = llist_creat(sizeof(struct score_st));
    int ret = 0;
    for(int i = 0;i < 7;i++)
    {
        tmp.id = i;
        snprintf(tmp.name, NAMESIZE,"std%d",i); 
        tmp.math = rand()%100;
        tmp.chinese = rand()%100;
        ret = llist_insert(handler,&tmp,LLIST_BACKWARD);
        if(ret != 0) printf("ERR");
    }
    llist_travel(handler,print_ss);
    int id = 3;
    struct score_st *data;
    data = llist_find(handler,&id,id_cmp);
    if(data == NULL) 
    {
        printf("ca not find");
    }
    else 
    {
        print_ss(data);
    }
    ret = llist_delete(handler,&id,id_cmp);
    if(ret) printf("llist_delted failted\n");
    llist_travel(handler,print_ss);

    llist_destory(handler);
    return 0;
}

list.c

#include <stdio.h>
#include <stdlib.h>
#include "list2222.h"
#include <string.h>
LLIST *llist_creat(int initsize)
{
    LLIST *new;
    new = malloc(sizeof(*new));
    if(new == NULL)
    {
        return NULL;
    }
    new->size = initsize;
    new->hade.data = NULL;
    new->hade.prev = &new->hade;
    new->hade.next = &new->hade;
    return new;
}

int llist_insert(LLIST *ptr,const void *data,int mode)
{
    struct llist_node_st *newnode;
    newnode = malloc(sizeof(*newnode));
    if(newnode == NULL)
    {
        return -1;
    }
    newnode->data = malloc(ptr->size); //这里是用户指定data的大小
    if(newnode->data == NULL)
        return -2;
    memcpy(newnode->data,data,ptr->size);
    if(mode == LLIST_FORWARD) //即头节点之后
    {
        newnode->prev = &ptr->hade;
        newnode->next = ptr->hade.next;
        newnode->prev->next = newnode;
        newnode->next->prev = newnode;
    }
    else if(mode == LLIST_BACKWARD)//即头节点之前
    {
        newnode->prev = ptr->hade.prev;
        newnode->next = &ptr->hade;
        newnode->prev->next = newnode;
        newnode->next->prev = newnode;
    }
    else
    {
        return -3;
    } 

    return 0;
}
void llist_destory(LLIST *ptr)
{
    struct llist_node_st *cur,*next;
    for(cur = ptr->hade.next; cur != &ptr->hade;cur = next)
    {
        next = cur->next;
        free(cur->data);
        free(cur);
    }
    free(ptr);
}
static struct llist_node_st *find_(LLIST *ptr,const void *key,llist_cmp *cmp)
{
    struct llist_node_st *cur;
    for(cur = ptr->hade.next; cur != &ptr->hade;cur = cur->next)
    {
        if(cmp(key,cur->data) == 0)
            break;
    }
    return cur;
    
}


void *llist_find(LLIST *ptr,const void *key,llist_cmp *cmp)
{
   return find_(ptr,key,cmp)->data;
}

void llist_travel(LLIST *ptr,llist_op *op)
{
    struct llist_node_st *cur;
    for(cur = ptr->hade.next;cur != &ptr->hade;cur = cur->next)
    {
        op(cur->data); //这里调用用户的打印回调函数把cur->data打印出来,通用性更强
    }
}
 
int llist_delete(LLIST *ptr,const void *key,llist_cmp *cmp) //只删除
{
    struct llist_node_st *node;
    node = find_(ptr,key,cmp);
    if(node == &ptr->hade)
        return -1;
    node->prev->next = node->next;
    node->next->prev = node->prev;
    free(node->data);
    free(node);
    return 0;
}
int llist_fetch(LLIST *ptr,const void *key,llist_cmp *cmp,void *data)//带数据回填的删除
{
    struct llist_node_st *node;
    node = find_(ptr,key,cmp);
    if(node == &ptr->hade)
        return -1;
    node->prev->next = node->next;
    node->next->prev = node->prev;
    if(data != NULL)
    {
        memcpy(data,node->data,ptr->size);
    }
    free(node->data);
    free(node);
    return 0;
}

list.h

#ifndef __LIST22222__ 
#define __LIST22222__
#include <stdio.h>
#include <stdlib.h>
#include "list2222.h"
#include <string.h>

#define LLIST_FORWARD   1
#define LLIST_BACKWARD   2
#define NAMESIZE 32
typedef void llist_op(const void *);  //函数类型 用于回调
typedef int llist_cmp(const void *,const void *);
struct score_st
{
    int id;
    char name[NAMESIZE];
    int math;
    int chinese;
};

typedef int datatype;
typedef struct llist_node_st
{
    void *data;
    struct llist_node_st *prev;
    struct llist_node_st *next;

};
typedef struct 
{
    int size;
    struct llist_node_st hade;

}LLIST;
LLIST *llist_creat(int initsize);
int llist_insert(LLIST *ptr,const void *data,int mode);
void llist_destory(LLIST *ptr);
// llist_delete();
void *llist_find(LLIST *ptr,const void *key,llist_cmp *cmp);
// llist_fetch();
void llist_travel(LLIST *ptr,llist_op *op);
int llist_delete(LLIST *ptr,const void *key,llist_cmp *cmp); //只删除
int llist_fetch(LLIST *ptr,const void *key,llist_cmp *cmp,void *data);//带数据回填的删除









#endif

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值