数据结构与算法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;
}
原文地址:https://www.cnblogs.com/chenyuxin/p/15218216.html