数据结构与算法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; }