双向链表

在学习redis源码的同时,模仿redis链表写成的。

头文件 adlist.h

#ifndef ADLIST_H
#define ADLIST_H
#include 
#include 
#include 

typedef struct listNode {
    struct listNode *prev;//前驱指针
    struct listNode *next;//后继指针
    void *value; //节点的值
} listNode;

typedef struct listIter {//链表迭代器
    listNode *next;
    int direction;//遍历方向
} listIter;

typedef struct list {//链表
    listNode *head;//链表头
    listNode *tail;//链表尾
    void *(*dup)(void *ptr); //复制函数指针
    void (*free)(void *ptr); //释放内存函数指针
    int (*match)(void *ptr, void *key); //比较函数指针
    unsigned long len; //链表长度
    struct test *mytest;
} list;

typedef struct test{
    void *data;
    struct test *next;
    //void (*free)(void *ptr);
}test;

typedef struct test1{
    int year;
    char *name;
}test1;

函数实现

list *listCreate(void)
{
    struct list *list;
    list=malloc(sizeof(*list));
    list->dup=NULL;
    list->len=0;
    list->free=NULL;
    list->head=list->tail=NULL;
    list->match=NULL;
    return list;
}

void listRelease(list *list)
{
    listNode *current,*next;
    unsigned long len;
    current=list->head;
    len = list->len;
    while(len--)
    {
        next=current->next;
        if(list->free)list->free(current);
        free(current);
        current=next;

    }
    free(list);
}

list* listAddnodeHead(list *list, void *value)
{
    listNode *node;
    node =malloc(sizeof(listNode));
    node->value=value;
    if(list->len!=0)
    {
        node->next=list->head;
        list->head->prev=node;
        list->head=node;
    }
    else {
        node->next=NULL;
        list->head=list->tail=node;
    }
    node->prev=NULL;
    list->len++;
    return list;
}

list *listAddNodeTail(list *list,void *value)
{
    listNode *node;
    node = malloc(sizeof(listNode));
    node->value=value;
    if(list->len!=0)
    {
        list->tail->next=node;
        node->prev=list->tail;
        node->next=NULL;
        list->tail=node;
    }
    else
    {
        list->tail=list->head=node;
        node->prev=NULL;
        node->next=NULL;
    }
    list->len++;
    node->next=NULL;
    return list;
}

list *insertnode(list *list,listNode *node,void *value,int after)
{
    listNode *new;
    new= malloc(sizeof(listNode));
    new->value=value;
    new->next=NULL;
    new->prev=NULL;
    if(after)
    {
        new->prev=node;
        new->next=node->next;
        if(list->tail==node)
            list->tail=new;
    }
    else {
        new->next=node;
        new->prev=node->prev;
        if(list->head==node)
            list->head=new;
    }
    if(new->prev!=NULL)
        new->prev->next=new;
    if(new->next!=NULL)
        new->next->prev=new;
    list->len++;
    return list;
}

list *delNode(list *list,listNode *node)
{
    if(node->prev)
        node->prev->next=node->next;
    else {
        list->head=node->next;
    }
    if(node->next)
        node->next->prev=node->prev;
    else {
        list->tail=node->prev;
    }
     if(list->free)list->free(node->value);
     free(node);
     list->len--;
     return list;
}

void printlist(list*list)
{
    listNode *node;
    node=list->head;
    if(list!=NULL)
    {    printf("mylist data is %s\n",node->value);
        while(node->next)
        {   node=node->next;
            printf("mylist data is %s\n",node->value);
        }

    }

}
int main()
{
    list *mylist;
    printf("%d  %d\n",sizeof(struct list),sizeof(*mylist));
    char str[10];
    mylist=listCreate();
//    for(int i=0;i<3;i++)//这种插入方式会出错,还没有想明白原因
//    {
//        printf("input data\n");
//        scanf("%s",str);
//        listAddNodeTail(mylist,str);
//    }
    listAddNodeTail(mylist,"11");
    listAddNodeTail(mylist,"22");
    printf("----input data\n");
    scanf("%s",str);
    listAddNodeTail(mylist,str);
    listAddNodeTail(mylist,"abcd");
    printlist(mylist);
    printf("----insert node operation:\n");
    insertnode(mylist,mylist->head->next,"insert",1);
    printlist(mylist);
    printf("----delete node operation:\n");
    delNode(mylist,mylist->head);
    printlist(mylist);
    return 0;
}

程序运行结果 

双向链表_第1张图片

你可能感兴趣的:(Linux,C语言)