【darknet 源码解析-01】list.h 与 list.c

本系列为darknet源码解析,本次解析src/list.h 与 src/list.c 两个。

list.h 中的包含的代码如下:

#ifndef LIST_H
#define LIST_H
#include "darknet.h"
 
list *make_list(); // 初始化链表
// 按值查找,注意这里的值是 void类型空指针,emmmm, list.c未定义,
int list_find(list *l, void *val); 
 
//
void list_insert(list *, void *);
 
 
void free_list_contents(list *l);
 
#endif
首先,我们分析list.h 中的源码,基础数据结构list 定义在 darknet.h 中,其定义如下:

typedef struct node{
    void *val; // 当前节点的内容是一个void类型的空指针
    struct node *next; // 指向当前节点的下一节点
    struct node *prev; //  指向当前节点的上一节点
} node;
 
typedef struct list{
    int size; // 当前list 的长度
    node *front; // 头指针,指针链表第一个节点
    node *back;  //尾指针,指针链表最后一个节点
} list;
可以发现,list就是我们熟悉的链表,可以发现在 list.h 中定义了4个函数,下面我们分别对解析这4个函数,我们将注解写在 list.c中,如下:

#include <stdlib.h>
#include <string.h>
#include "list.h"
 
 
// 初始化链表
list *make_list()
{
        // 分配存储空间
    list *l = malloc(sizeof(list));
        // 初始化链表长度、头指针、尾指针
    l->size = 0; 
    l->front = 0;
    l->back = 0;
    return l;
}
 
/*
void transfer_node(list *s, list *d, node *n)
{
    node *prev, *next;
    prev = n->prev;
    next = n->next;
    if(prev) prev->next = next;
    if(next) next->prev = prev;
    --s->size;
    if(s->front == n) s->front = next;
    if(s->back == n) s->back = prev;
}
*/
 
// 链表的删除操作,删除尾指针所指节点,即最后一个节点
void *list_pop(list *l){
    // 如果链表为空
    if(!l->back) return 0;
    // node *b 指向最后一个节点
    node *b = l->back;
    void *val = b->val;
    // 更新尾指针,尾指针指向b的前一节点,即倒数第二节点。
    l->back = b->prev;
    // 如果倒数第二节点存在
    if(l->back) l->back->next = 0; //尾指针next置为null
    free(b); // 释放最后一个节点的存储空间
    --l->size; // 链表长度 -1
    
    return val; // 返回被删除节点保存的值
}
 
// 链表按序插入操作
void list_insert(list *l, void *val)
{
        // 为新节点申请存储空间
    node *new = malloc(sizeof(node));
        // 赋值
    new->val = val;
    new->next = 0; // next置null
        
        // 如果链表l 尾指针为空,则说明此时链表l长度为0
    if(!l->back){
        l->front = new; // 更新头指针
        new->prev = 0; // 此时该节点为头节点,故头节点的上一节点为null
    }else{ //如果链表l 尾指针非空,则说明此时l长度 >=1
        l->back->next = new; // 更新当前节点的上一节点的next指针域
        new->prev = l->back; // 更新当前节点的prev指针域
    }
    l->back = new; // 更新链表l的尾指针
    ++l->size; // 链表长度 +1 
}
 
// 释放链表节点的存储空间,从节点n开始释放,一直释放到最后一个节点。
void free_node(node *n)
{
    node *next;
    while(n) {
        next = n->next; // 获取下一节点地址
        free(n); // 释放当前节点存储空间
        n = next; //更新n,n指向下一节点
    }
}
 
// 释放整个链表l的存储空间
void free_list(list *l)
{
    free_node(l->front);
    free(l);
}
 
// 对链表所有节点的值【节点中值为void 类型指针】 的存储空间释放
void free_list_contents(list *l)
{
    node *n = l->front;
    while(n){
        free(n->val);
        n = n->next;
    }
}
 
// 二维指针,这里的操作是将链表l中所有节点的值进行保存,
// 因为每个节点里保存的值是 void类型的指针,故指针的指针,即二维指针
void **list_to_array(list *l)
{
    // 分配存储空间,长度l-size, 每个空间大小为一个void类型指针
    void **a = calloc(l->size, sizeof(void*));
    int count = 0;
    node *n = l->front; // 工作指针n指向头节点
    while(n){
        // 将工作指针n指向节点的值保存到a中
        a[count++] = n->val;
        n = n->next;// 更新工作指针
    }
    return a;
}
完,
————————————————

                            版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
                        
原文链接:https://blog.csdn.net/caicaiatnbu/article/details/95015014

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值