• NetBSD Make源代码阅读二:链表之创建与销毁


    1.创建链表

    /*-
     *-----------------------------------------------------------------------
     * Lst_Init --
     *    创建并初始化一个链表 
     *
     * 输入:
     *    circ    如果是循环链表则为TRUE     
     *
     * 结果:
     *    创建好的链表(空链表).
     *
     * 副作用:
     *    链表已经创建,还需要做啥?
     *
     *-----------------------------------------------------------------------
     */
    Lst
    Lst_Init(Boolean circ)
    {
        List    nList;          /* List为链表结构指针类型*/
    
        PAlloc (nList, List);    /*分配链表结构内存,并让nList指向该结构*/
    
        nList->firstPtr = NULL;     /*初始化链表结构各成员变量*/
        nList->lastPtr = NULL;
        nList->isOpen = FALSE;
        nList->isCirc = circ;
        nList->atEnd = Unknown;
    
        return (nList);           /*返回链表结构指针*/
    }

      其实,这个函数就是分配链表结构内存,然后初始化结构成员变量。值得注意的是,分配链表结构内存的操作PAlloc。

    /*
     * PAlloc (var, ptype) --
     *    分配 'ptype' 类型结构的内存,并把地址赋给变量 'var'
     */
    #define    PAlloc(var,ptype)    var = (ptype) bmake_malloc(sizeof *(var))
    /*
     * bmake_malloc --
     *    调用malloc分配内存,如果出错,打印错误信息到stderr并退出
     */
    void *
    bmake_malloc(size_t len)
    {
        void *p;
    
        if ((p = malloc(len)) == NULL)
            enomem();
        return(p);
    }

    2. 销毁链表

        链表结构分为两部分一个是链表头结构List,一个是其节点ListNode。而在ListNode中包含一个指向客户自定义数据的指针。下面这个函数,为了遍历各个节点方便,把最后一个节点的nextptr设成null,这主要针对循环列表。

      链表销毁的步骤:

      1.依次释放链表的节点,如果指定了freeProc,则调用它释放节点对应的客户数据

      2.然后释放链表头结构。

    /*-
     *-----------------------------------------------------------------------
     * Lst_Destroy --
     *    销毁链表并释放其所有资源。如果指定了freeProc ,则在每个节点释放前
     *    对其应用该函数。
     *    
     *
     * 返回值:
     *    无
     *
     * 副作用:
     *    所给的链表完全销毁
     *
     *-----------------------------------------------------------------------
     */
    void
    Lst_Destroy(Lst list, FreeProc *freeProc)
    {
        ListNode    ln;
        ListNode    tln = NULL;
    
        if (list == NULL)
        return;
    
        /* 为了让遍历更简单 */
        if (list->lastPtr != NULL)                    /×如果所给的链表不是空的×/
        list->lastPtr->nextPtr = NULL;      
        else {
        free(list);                                    /×释放链表头结构×/
        return;
        }
    
        if (freeProc) {
        for (ln = list->firstPtr; ln != NULL; ln = tln) {
             tln = ln->nextPtr;
             freeProc(ln->datum);    /×释放节点指向的数据*/
             free(ln);                      /*释放节点*/
        }
        } else {
        for (ln = list->firstPtr; ln != NULL; ln = tln) {
             tln = ln->nextPtr;
             free(ln);
        }
        }
    
        free(list);   / *释放链表头×/
    }
  • 相关阅读:
    天府大讲堂:5G时代的物联网发展趋势与产业变革
    一步步教你轻松学奇异值分解SVD降维算法
    一步步教你轻松学支持向量机SVM算法之案例篇2
    一步步教你轻松学支持向量机SVM算法之理论篇1
    一步步教你轻松学主成分分析PCA降维算法
    一步步教你轻松学关联规则Apriori算法
    一步步教你轻松学K-means聚类算法
    一步步教你轻松学逻辑回归模型算法
    一步步教你轻松学朴素贝叶斯模型实现篇2
    一步步教你轻松学朴素贝叶斯模型算法理论篇1
  • 原文地址:https://www.cnblogs.com/RbtreeLinux/p/3530441.html
Copyright © 2020-2023  润新知