C语言 list 链表

一、list简介

这里用双向链表实现,包含插入头、插入尾、删除头、删除尾等操作。
注意:考虑性能,这边所有操作均不是线程安全的,如多线程使用请合理构建或自行加锁。

二、list 包含方法

2.1. push_front

  • 功能
    插入数据到 list 头部
  • 参数
    list:list指针,data:插入数据指针,len:插入数据
  • 返回值 int
    0:成功, -1 : 超过链表最大长度或者数据长度过长,-2:内存申请失败

2.2. push_back

  • 功能
    插入数据到 list 尾部
  • 参数
    list:list指针,data:插入数据指针,len:插入数据
  • 返回值 int
    0:成功, -1 : 超过链表最大长度或者数据长度过长,-2:内存申请失败

2.3. front

  • 功能
    获取 list 头部数据
  • 参数
    list:list指针
  • 返回值 void*
    NULL:失败或者list头为空, 其他 : list头部数据

2.3. back

  • 功能
    获取 list 尾部数据
  • 参数
    list:list 指针
  • 返回值 void*
    NULL:失败或者list尾为空, 其他 : list尾部数据

2.2. pop_front

  • 功能
    删除 list 头部节点
  • 参数
    list:list指针
  • 返回值 void

2.2. pop_back

  • 功能
    删除 list 尾部节点
  • 参数
    list:list指针
  • 返回值 void

2.2. size

  • 功能
    获取 list 节点数量
  • 参数
    list:list指针
  • 返回值 int
    list 节点数量

2.2. empty

  • 功能
    list 是否为空
  • 参数
    list:list指针
  • 返回值 bool
    true:list为空,false:list不为空

2.2. clear

  • 功能
    清空 list 节点
  • 参数
    list:list指针
  • 返回值 void

三、源码

仓库地址

码云仓库

example

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "list.h"
#include <mcheck.h>

typedef struct _DATA_
{
    int len;
    char buff[];
} DATA_t;

void free_data(void* _data)
{
    DATA_t* data = (DATA_t*)_data;
    if(NULL == data)
        return;
    free(data);
}

int main()
{
    setenv("MALLOC_TRACE", "/tmp/mem.txt", 1);
    mtrace();

    LIST_t *list = create_list(10, 248, free_data);
    if (NULL == list)
    {
        printf("Create list error\n");
        exit(-1);
    }
    
    for(int i = 0; i < 2; i++)
    {
        char *num_str = NULL;
        asprintf(&num_str, "%d", i);
        if(num_str == NULL)
        {
            printf("Create num error\n");
            exit(-1);
        }
        
        DATA_t *data = (DATA_t *)malloc(sizeof(DATA_t) + strlen(num_str) * sizeof(char) + 1);
        if (NULL == data)
        {
            printf("Create data error\n");
            exit(-1);
        }
        bzero(data, sizeof(DATA_t) + strlen(num_str) * sizeof(char) + 1);
        data->len = strlen(num_str);
        strcpy(data->buff, num_str);
        int err = list->push_back(list, data, sizeof(DATA_t) + data->len * sizeof(char) + 1);
        if(err < 0)
            printf("push back error, errcode:%d", err);
        
        free(num_str);
        free(data);
    }

    printf("list size:%d\n", list->size(list));
    while(!list->empty(list))
    {
        DATA_t *it = (DATA_t *)list->front(list);
        if (NULL == it)
        {
            printf("Get front error\n");
            exit(-1);
        }
        printf("len:%d, buff:%.*s\n", it->len, it->len, it->buff);

        list->pop_front(list);
    }
    printf("list size:%d\n", list->size(list));
    list->clear(list);
    printf("list size:%d\n", list->size(list));
    list->destruct(&list);
    muntrace();
}

  • 4
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
单向链表是一种常见的数据结构,可以动态地存储一系列节点。每个节点包含数据和指向下一个节点的指针。 在C语言中,可以通过定义一个表示节点的结构体来实现单向链表: ```c struct Node { int data; struct Node* next; }; ``` 其中 `data` 用于存储节点的数据,`next` 指向下一个节点。链表的头节点可以通过一个指针来表示: ```c struct Node* head = NULL; ``` 现在,我们来实现插入节点的功能。 首先,需要创建一个新的节点,并为其分配内存空间: ```c struct Node* newNode = (struct Node*)malloc(sizeof(struct Node)); ``` 然后,可以给节点的 `data` 赋值: ```c newNode->data = newData; ``` 接下来,将新节点插入到链表中。 如果链表是空的,即头节点为 `NULL`,那么将新节点作为头节点: ```c if (head == NULL) { head = newNode; newNode->next = NULL; } ``` 否则,需要找到插入位置的前一个节点,将其 `next` 指向新节点,同时将新节点的 `next` 指向原来的后续节点: ```c else { struct Node* temp = head; while (temp->next != NULL) { temp = temp->next; } temp->next = newNode; newNode->next = NULL; } ``` 最后,记得要释放新节点的内存空间,以防止内存泄漏: ```c free(newNode); ``` 这样,就完成了单向链表的节点插入操作。 需要注意的是,在实际中,还需要考虑边界条件、异常情况的处理等,以确保代码的健壮性和可靠性。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值