zoukankan      html  css  js  c++  java
  • 数据结构与算法7 — 单链表

    尊重作者劳动成果,转载请注明出处,谢谢!

    1. linkList.h

    #ifndef linkList_H
    #define linkList_H
    
    #include <stddef.h>
    #include "delegate.h"
    
    //链表节点
    typedef struct linkNode
    {
        void *data;            //节点数据
        struct linkNode *next; //下一个节点
    } LinkNode;
    
    //链表
    typedef struct linkList
    {
        struct linkNode *header; //头节点
        size_t dataSize;         //节点数据大小
        size_t size;             //节点个数
    } LinkList;
    
    //定义该宏可以直观的看出链表元素的数据类型,比如:LinkList(int)
    #define LinkList(type) LinkList
    
    #ifdef __cplusplus
    extern "C"
    {
    #endif
        int linkList_init(LinkList *llist, size_t dataSize);
        void linkList_free(LinkList *llist);
        void linkList_clear(LinkList *llist);
        size_t linkList_length(const LinkList *llist);
        int linkList_add(LinkList *llist, const void *data);
        int linkList_insert(LinkList *llist, const void *data, size_t index);
        void linkList_remove(LinkList *llist, const void *data, Comparison comparison);
        void linkList_removeAll(LinkList *llist, const void *data, Comparison comparison);
        void linkList_removeAt(LinkList *llist, size_t index);
        void *linkList_getData(const LinkList *llist, size_t index);
        void linkList_setData(LinkList *llist, size_t index, const void *data);
        void *linkList_firstDataOf(const LinkList *llist, const void *data, Comparison comparison);
        void *linkList_lastDataOf(const LinkList *llist, const void *data, Comparison comparison);
    #ifdef __cplusplus
    }
    #endif
    
    #endif

    2. linkList.c

    #include "linkList.h"
    #include <stdlib.h>
    #include <string.h>
    
    //创建链表节点
    static LinkNode *linkList_createNode(const void *data, size_t dataSize)
    {
        LinkNode *node = (LinkNode *)malloc(sizeof(LinkNode));
        if (node == NULL)
            return NULL;
    
        node->data = malloc(dataSize);
        if (node->data == NULL)
        {
            free(node);
            return NULL;
        }
    
        memcpy(node->data, data, dataSize);
        node->next = NULL;
        return node;
    }
    
    //释放链表节点
    static void linkList_freeNode(LinkNode *node)
    {
        if (node == NULL)
            return;
    
        if (node->data != NULL)
        {
            free(node->data);
            node->data = NULL;
        }
    
        node->next = NULL;
        free(node);
    }
    
    //初始化
    int linkList_init(LinkList *llist, size_t dataSize)
    {
        if (llist == NULL || dataSize <= 0)
            return -1;
    
        llist->size = 0;
        llist->header = NULL;
        llist->dataSize = dataSize;
        return 0;
    }
    
    //初始化
    void linkList_free(LinkList *llist)
    {
        if (llist == NULL)
            return;
    
        linkList_clear(llist);
        llist->dataSize = 0;
    }
    
    //清空链表
    void linkList_clear(LinkList *llist)
    {
        if (llist == NULL)
            return;
    
        LinkNode *node;
        while (llist->header != NULL)
        {
            node = llist->header;
            llist->header = node->next;
            linkList_freeNode(node);
        }
    
        llist->size = 0;
    }
    
    //获取链表长度
    size_t linkList_length(const LinkList *llist)
    {
        if (llist == NULL || llist->header == NULL)
            return 0;
    
        return llist->size;
    }
    
    //添加节点
    int linkList_add(LinkList *llist, const void *data)
    {
        if (llist == NULL)
            return -1;
    
        LinkNode *node = linkList_createNode(data, llist->dataSize);
        if (node == NULL)
            return -1;
    
        if (llist->header == NULL)
        {
            llist->header = node;
        }
        else
        {
            LinkNode *header = llist->header;
            while (header->next != NULL)
            {
                header = header->next;
            }
    
            header->next = node;
        }
    
        llist->size++;
        return 0;
    }
    
    //在指定位置插入节点
    int linkList_insert(LinkList *llist, const void *data, size_t index)
    {
        if (llist == NULL)
            return -1;
    
        if (index > llist->size)
            return -1;
    
        LinkNode *newNode = linkList_createNode(data, llist->dataSize);
        if (newNode == NULL)
            return -1;
    
        //头节点为空或插入位置为0,那么直接修改头结点
        if (llist->header == NULL || index == 0)
        {
            newNode->next = llist->header;
            llist->header = newNode;
        }
        else //插入位置大于0
        {
            size_t i = 1;
            LinkNode *pFront = llist->header;
            LinkNode *pNext = llist->header->next;
    
            while (pNext != NULL)
            {
                if (i == index)
                    break;
    
                pFront = pNext;
                pNext = pNext->next;
                i++;
            }
    
            newNode->next = pNext;
            pFront->next = newNode;
        }
    
        llist->size++;
        return 0;
    }
    
    //删除第一个满足给定条件的节点
    void linkList_remove(LinkList *llist, const void *data, Comparison comparison)
    {
        if (llist == NULL || llist->header == NULL)
            return;
    
        //比较头节点
        if (comparison(llist->header->data, data, llist->dataSize) == 0)
        {
            LinkNode *header = llist->header;
            llist->header = header->next;
            linkList_freeNode(header);
            llist->size--;
        }
        else
        {
            LinkNode *pFront = llist->header;
            LinkNode *pNext = llist->header->next;
    
            while (pNext != NULL)
            {
                if (comparison(pNext->data, data, llist->dataSize) == 0) //找到值相同的节点
                {
                    pFront->next = pNext->next;
                    linkList_freeNode(pNext);
                    llist->size--;
                    break;
                }
    
                pFront = pNext;
                pNext = pNext->next;
            }
        }
    }
    
    //删除所有满足给定条件的节点
    void linkList_removeAll(LinkList *llist, const void *data, Comparison comparison)
    {
        if (llist == NULL || llist->header == NULL)
            return;
    
        //比较头节点
        while (llist->header != NULL)
        {
            if (comparison(llist->header->data, data, llist->dataSize) != 0)
                break;
    
            LinkNode *header = llist->header;
            llist->header = header->next;
            linkList_freeNode(header);
            llist->size--;
        }
    
        if (llist->header != NULL)
        {
            LinkNode *pFront = llist->header;
            LinkNode *pNext = llist->header->next;
    
            while (pNext != NULL)
            {
                if (comparison(pNext->data, data, llist->dataSize) == 0) //找到值相同的节点
                {
                    pFront->next = pNext->next;
                    linkList_freeNode(pNext);
                    pNext = pFront->next; //继续处理下一个节点
                    llist->size--;
                    continue;
                }
    
                pFront = pNext;
                pNext = pNext->next;
            }
        }
    }
    
    //删除指定位置的节点
    void linkList_removeAt(LinkList *llist, size_t index)
    {
        if (llist == NULL || llist->header == NULL)
            return;
    
        //删除头结点
        if (index == 0)
        {
            LinkNode *header = llist->header;
            llist->header = header->next;
            linkList_freeNode(header);
            llist->size--;
        }
        else //删除位置大于0
        {
            size_t i = 1;
            LinkNode *pFront = llist->header;
            LinkNode *pNext = llist->header->next;
    
            while (pNext != NULL)
            {
                if (i == index) //找到删除的位置
                {
                    pFront->next = pNext->next;
                    linkList_freeNode(pNext);
                    llist->size--;
                    break;
                }
    
                pFront = pNext;
                pNext = pNext->next;
            }
        }
    }
    
    //获取指定索引的节点
    static LinkNode *linkList_getNode(const LinkList *llist, size_t index)
    {
        if (llist == NULL)
            return NULL;
    
        if (index >= llist->size)
            return NULL;
    
        size_t i = 0;
        LinkNode *pNode = llist->header;
    
        while (pNode != NULL)
        {
            if (i == index)
                break;
    
            pNode = pNode->next;
            i++;
        }
    
        return pNode;
    }
    
    //获取指定索引的节点的数据
    void *linkList_getData(const LinkList *llist, size_t index)
    {
        LinkNode *pNode = linkList_getNode(llist, index);
        if (pNode == NULL)
            return NULL;
    
        return pNode->data;
    }
    
    //修改节点
    void linkList_setData(LinkList *llist, size_t index, const void *data)
    {
        LinkNode *pNode = linkList_getNode(llist, index);
        if (pNode == NULL)
            return;
    
        memcpy(pNode->data, data, llist->dataSize);
    }
    
    //查找第一个等于给定条件的节点
    void *linkList_firstDataOf(const LinkList *llist, const void *data, Comparison comparison)
    {
        if (llist == NULL)
            return NULL;
    
        LinkNode *pNode = llist->header;
    
        while (pNode != NULL)
        {
            if (comparison(pNode->data, data, llist->dataSize) == 0)
                break;
    
            pNode = pNode->next;
        }
    
        return pNode != NULL ? pNode->data : NULL;
    }
    
    //查找最后一个等于给定条件的节点
    void *linkList_lastDataOf(const LinkList *llist, const void *data, Comparison comparison)
    {
        if (llist == NULL)
            return NULL;
    
        LinkNode *header = llist->header;
        LinkNode *pNode = NULL;
    
        while (header != NULL)
        {
            if (comparison(header->data, data, llist->dataSize) == 0)
                pNode = header;
    
            header = header->next;
        }
    
        return pNode != NULL ? pNode->data : NULL;
    }
  • 相关阅读:
    POJ 3683 Priest John&#39;s Busiest Day (2-SAT+输出可行解)
    Codeforces #2B The least round way(DP)
    避免死锁的银行家算法C++程序实现
    源代码编译安装MySQL5.6.12具体过程
    Android 设计模式
    Java与设计模式-适配器模式
    Java和Flex整合报错(五)
    三层架构—再思考
    怎样让DBGrid在按住Shift点鼠标的同时能将连续范围的多行选中?
    找出你的短板
  • 原文地址:https://www.cnblogs.com/chenyuxin/p/15218216.html
Copyright © 2011-2022 走看看