简单的通用链表实现

最近项目需要用到链表, 并且是建立三个不同的专用链表,为了对代码加以简化,特采用通用链表来实现代码功能!

本链表是在linux下运行的,因此含有部分系统函数。

本人对指针理解较为粗糙,不能保证代码正确性,仅作自己总结而用!

代码未加封装,只有简单的实现函数。


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdbool.h>


typedef struct listnode
{
    struct listnode *next;
    struct listnode *prev;
    void            *data;
}List;


//新建链表头
List *createNode(void)
{
    List *head = (List *)malloc(sizeof(List));
    if(NULL == head)
    {
        printf("Usage : malloc error !\n");
        return NULL;
    }

    head->next = head->prev = head;

    return head;
}

//尾插法
List *tailInsert(List *head, void *data)
{
    List *node = (List *)malloc(sizeof(List));
    if(NULL == node)
    {
        printf("Usage : malloc error !\n");
        return NULL;
    }
    node->data = data;

    head->prev->next = node;
    node->prev = head->prev;
    head->prev = node;
    node->next = head;

    return head;
}

//摧毁链表
void destroyList(List **head)
{
    List *tmp = NULL;
    List *next = NULL;
    if((*head)->next == *head)
    {
        return;
    }
    for(tmp=*head; tmp->next!=*head; tmp=next)
    {
        next = tmp->next;
        free(tmp);
    }
    *head = NULL;
}

//按compare函数来检索链表节点
List *searchList(List *head, void *key, bool (*compare)(void *, void *))
{
    List *ptr = head;
    while(ptr->next != head)
    {
        ptr = ptr->next;
        if(compare(ptr->data, key))
        {
            return ptr;
        }
    }

    return NULL;
}

//删除compare函数检索到的节点
List *deleteList(List *head, void *key, bool(*compare)(void *, void*))
{
    List *ptr = head;
    while(ptr->next != head)
    {
        ptr = ptr->next;
        if(compare(ptr->data, key))
        {
            ptr->prev->next = ptr->next;
            ptr->next->prev = ptr->prev;
            free(ptr);
            break;
        }
    }

    return head;
}

//打印链表
void printList(List *head, void (*print)(void *))
{
    List *ptr = head;
    while(ptr->next != head)
    {
        ptr = ptr->next;
        print(ptr->data);
    }
}

//把链表存入文件
void saveList(List *head, const char *filename, size_t size)
{
    int fd = open(filename, O_CREAT | O_WRONLY | O_TRUNC, 0777);
    if(-1 == fd)
    {
        printf("Usage : open error !\n");
        return;
    }

    List *ptr = head;
    while(ptr->next != head)
    {
        ptr = ptr->next;
        write(fd, ptr->data, size);
    }
    close(fd);

    destroyList(&head);
}

//从文件读入链表
List *readList(const char *filename, size_t size)
{
    int fd, ret;
    List *head = createNode();

    if(access(filename, F_OK) != 0)
    {
        close(open(filename, O_CREAT | O_APPEND, 0777));
    }
    fd = open(filename, O_RDONLY);
    if(-1 == fd)
    {
        printf("Usage : open error !\n");
        return NULL;
    }
    while(1)
    {
        void *data;
        data = malloc(size);
        ret = read(fd, data, size);
        if(0 == ret)
        {
            break;
        }
        tailInsert(head, data);
    }
    close(fd);

    return head;
}

简单测试:

typedef struct action
{
    char name[20];
    int id;
}action_t;

//比较函数
bool compare(void *data, void *key)
{
    action_t *act = (action_t *)data;
    int id = (int)key;
    if(act->id == id)
    {
        return true;
    }
    return false;
}

//打印函数
void print(void *data)
{
    action_t *act = (action_t *)data;
    printf("id   = %d\t", act->id);
    printf("name = %s\n", act->name);
}


int main(void)
{
    char *filename = "action.txt";

    action_t test1 = {"zhao", 1};
    action_t test2 = {"qian", 2};
    action_t test3 = {"yang", 3};
    action_t test4 = {"ling", 4};
    action_t test5 = {"zhou", 5};

    List *head = createNode();
    tailInsert(head, (void *)(&test1));
    tailInsert(head, (void *)(&test2));
    tailInsert(head, (void *)(&test3));
    tailInsert(head, (void *)(&test4));
    tailInsert(head, (void *)(&test5));

    printList(head, print);

    //存入文件
    saveList(head, filename, sizeof(action_t));

    //从文件读取
    List *list = readList(filename, sizeof(action_t));
    if(deleteList(list, (void *)1, compare))
    {
        printf("删除id为1的节点,成功则打印!\n");
    }
    //检验是否删除成功
    printList(list, print);

    return 0;
}




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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值