链表是一种物理存储单元上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的。(百度百科)。
通俗来讲,链表的数据存储位置不确定,但是可以通过链表结构中的指针指向相应的数据,从而达到逻辑连续的目的。
链表适用于长度不确定的数据结构,插入或删除某个元素不需要调整整个数据结构。
链表不适用于频繁查找某个数据。
以下为源码,包含单链表,双链表和循环双链表
list.h
#ifndef __LIST_H__ #define __LIST_H__ #include "stm32f10x.h" #include "stdlib.h" #define MaxListLength 20 #define SingleList 1 #ifdef SingleList #define SingleListMode (1) typedef struct ListNode { uint32_t value; struct ListNode *pNext; }ListNode; #endif #ifdef DoubleList #define DoubleListMode (1) typedef struct ListNode { uint32_t value; struct ListNode *pNext; struct ListNode *pLast; }ListNode; #endif #ifdef LoopList #define LoopListMode (1) typedef struct ListNode { uint32_t value; struct ListNode *pNext; struct ListNode *pLast; }ListNode; #endif typedef unsigned int ListState; uint32_t List_GetListNodeCnt(ListNode *pHead); ListState List_Init(ListNode * pHead,const uint32_t value); ListState List_InsertNode(ListNode *pHead,const uint32_t node ,const uint32_t value); ListState List_DeleteNode(ListNode *pHead,const uint32_t node); ListState List_DeleteVal (ListNode *pHead,const uint32_t value); ListNode* List_GetValueList (ListNode *pHead,const uint32_t value); #endif
以下为list.c
#include "list.h" static ListNode ListResult = {0}; /** * @name List_Init. * @brief Creat a list head. * @param ListNode * pHead: Head of the list. uint32_t value: Value of the head. * @retval 0 : Succeed. 1 : There is no stack of head. * @author Jiao Wo Yi Sheng Xiao Ming Ge. * @Date 2018.5.30. **/ ListState List_Init(ListNode * pHead,const uint32_t value) { // pHead = (ListNode *)malloc(sizeof(ListNode)); if(pHead == NULL) return 1; #ifdef SingleListMode pHead->pNext = NULL; pHead->value = value; #endif #ifdef DoubleListMode pHead->pNext = NULL; pHead->value = value; pHead->pLast = NULL; #endif #ifdef LoopListMode pHead->pNext = pHead; pHead->value = value; pHead->pLast = pHead; #endif return 0; } /** * @name List_NodeCnt. * @brief Get list counters. * @param ListNode * pHead: Head of the list. * @retval length : list counters. * @author Jiao Wo Yi Sheng Xiao Ming Ge. * @Date 2018.5.30. **/ static uint32_t List_NodeCnt(ListNode *pHead) { ListNode * next = pHead; uint32_t length = 0; #ifdef LoopListMode while(next->pNext != pHead) {length ++; next = next->pNext;} #endif #ifndef LoopListMode while(next->pNext != NULL) {length ++; next = next->pNext;} #endif return length; } uint32_t List_GetListNodeCnt(ListNode *pHead) { return (List_NodeCnt(pHead)); } /** * @name List_InsertNode. * @brief Insert a value at node in list. * @param ListNode * pHead: Head of the list. uint32_t node : The place where you insert the value in the list. uint32_t value: Value you will insert. * @retval 0 : Succeed. 1 : You can't insert value in front of the head. 2 : The current list length is langer than MaxListLength. 3 : Head of list is NULL * @author Jiao Wo Yi Sheng Xiao Ming Ge. * @Date 2018.5.30 **/ ListState List_InsertNode(ListNode *pHead,const uint32_t node ,const uint32_t value) { ListNode * curr = (ListNode *)malloc(sizeof(ListNode)); ListNode * next = pHead; uint32_t temp = 0,length = 0; if(pHead == NULL) return 3; length = List_GetListNodeCnt(next); if(length > MaxListLength) return 2; if(node == 0) return 1; /* 4 : The insert node is beyond current list length. */ // if(node > ListLength) // return 4; #ifdef SingleListMode for(temp = 0;temp < node - 1;temp++) { if(next->pNext == NULL) break; next = next->pNext; } curr->pNext = next->pNext; curr->value = value; next->pNext = curr; #endif #ifdef DoubleListMode for(temp = 0;temp < node - 1;temp++) { if(next->pNext == NULL) break; next = next->pNext; } curr->value = value; curr->pLast = next; curr->pNext = next->pNext; if(next->pNext != NULL) next->pNext->pLast = curr; next->pNext = curr; #endif #ifdef LoopListMode for(temp = 0;temp < node - 1;temp++) { if(next->pNext == pHead) break; next = next->pNext; } curr->value = value; curr->pLast = next; curr->pNext = next->pNext; next->pNext->pLast = curr; next->pNext = curr; #endif return 0; } /** * @name List_DeleteNode. * @brief Delete a node in list. * @param ListNode * pHead: Head of the list. uint32_t node : The place where you delete the value in the list. * @retval 0 : Succeed. 1 : The delete node is beyond current list length. 2 : The current list length is langer than MaxListLength. 3 : The head of the list can't be deleted. 4 : Head of list is NULL * @author Jiao Wo Yi Sheng Xiao Ming Ge. * @Date 2018.5.30 **/ ListState List_DeleteNode(ListNode *pHead,const uint32_t node) { ListNode * next = pHead; ListNode * curr; uint32_t temp = 0; uint32_t length = 0; if(pHead == NULL) return 4; length = List_GetListNodeCnt(next); if(length > MaxListLength) return 2; if(node > length) return 1; if(node == 0) return 3; #ifdef SingleListMode for(temp = 0;temp < node - 1;temp++) { if(next->pNext == NULL) break; next = next->pNext; } curr = next->pNext; next->pNext = curr->pNext; free(curr); return 0; #endif #ifdef DoubleListMode for(temp = 0;temp < node - 1;temp++) { if(next->pNext == NULL) break; next = next->pNext; } curr = next->pNext; curr->pNext->pLast = next; next->pNext = curr->pNext; free(curr); return 0; #endif #ifdef LoopListMode for(temp = 0;temp < node - 1;temp++) { if(next->pNext == pHead) break; next = next->pNext; } curr = next->pNext; curr->pNext->pLast = next; next->pNext = curr->pNext; free(curr); return 0; #endif } /** * @name List_DeleteVal. * @brief Delete a value list. * @param ListNode * pHead: Head of the list. uint32_t value: The value which you delete in the list. * @retval 0 : Succeed. 1 : The delete node is beyond current list length. 2 : Head of list is NULL * @author Jiao Wo Yi Sheng Xiao Ming Ge. * @Date 2018.5.30 **/ ListState List_DeleteVal(ListNode *pHead, const uint32_t value) { ListNode *next = pHead; uint32_t i = 0; uint32_t temp = 0; uint32_t length = 0; if(pHead == NULL) return 2; length = List_GetListNodeCnt(next); do { i++; next = next->pNext; if(next->value == value) { List_DeleteNode(pHead,i - temp); temp ++; } }while(i<length); if(temp == 0) return 1; return 0; } /** * @name List_FindValue. * @brief Delete a value list. * @param ListNode * pHead: Head of the list. uint32_t value: The value which you delete in the list. * @retval 0 : Succeed. 1 : The delete node is beyond current list length. 2 : Head of list is NULL * @author Jiao Wo Yi Sheng Xiao Ming Ge. * @Date 2018.5.30 **/ static ListNode* List_FindValue (ListNode *pHead,const uint32_t value) { ListNode *next = pHead; uint32_t temp = 0,i = 0; uint32_t length = GetListNodeCnt(pHead); ListInit(&ListResult,0); do { if(next->value == value) { temp ++; List_InsertNode(&ListResult,temp,i); } i++; next = next->pNext; }while(i<length); return (&ListResult); } ListNode* List_GetValueList(ListNode *pHead,const uint32_t value) { return (List_FindValue(pHead,value)); }