链表是一种常见的基础数据结构,结构体指针在这里得到了充分的利用。链表可以动态的进行存储分配,也就是说,链表是一个功能极为强大的数组,他可以在节点中定义多种数据类型,还可以根据需要随意增添,删除,插入节点。链表都有一个头指针,一般以head来表示,存放的是一个地址。链表中的节点分为两类,头结点和一般节点,头结点是没有数据域的。链表中每个节点都分为两部分,一个数据域,一个是指针域。说到这里你应该就明白了,链表就如同车链子一样,head指向第一个元素:第一个元素又指向第二个元素;……,直到最后一个元素,该元素不再指向其它元素,它称为“表尾”,它的地址部分放一个“NULL”(表示“空地址”),链表到此结束。
作为有强大功能的链表,对他的操作当然有许多,比如:链表的创建,修改,删除,插入,输出,排序,反序,清空链表的元素,求链表的长度等等。
这里在mcu上运行OK:
C文件:
Node Pnode;void SListInit(SList* s) { s->_pHead = NULL;}//构建一个结点 PNode BuySListNode(SDataType _data){ PNode node = (PNode)malloc(sizeof(Node)); if (node) { node->_data = _data; node->_PNext = NULL; } return node;}/*尾插,首先要创建一个新节点,然后判断链表当前是否有节点,若没有,则直接让第一个节点指向新节点,若有,找到最后一个节点,让他指向新节点*/void SListPushBack(SList* s, SDataType data) { //找链表最后一个节点 PNode pNewNode = BuySListNode(data); if (s->_pHead == NULL) {//链表没有节点的情况 s->_pHead = pNewNode; } else { PNode pCur = s->_pHead; while (pCur->_PNext) { pCur = pCur->_PNext; } //让最后一个节点指向新节点 pCur->_PNext = pNewNode; }}/*查找某个特征的节点*/PNode SListFind(SList* s, SDataType data) { PNode pCur = s->_pHead; while (pCur) { if (pCur->_data == data) { return pCur; } pCur = pCur->_PNext; } return NULL;}/*删除给定pos位置的节点*/void SListErase(SList* s, PNode pos) { if (pos == NULL || s->_pHead == NULL) { return; } if (pos== s->_pHead) { s->_pHead = pos->_PNext; } else { PNode pPrePos = s->_pHead; while (pPrePos&&pPrePos->_PNext != pos) { pPrePos = pPrePos->_PNext; } pPrePos->_PNext = pos->_PNext; } free(pos);}//获取链表有效节点的个数int SListSize(SList* s){ int count = 0; PNode pCur = s->_pHead; while (pCur) { count++; pCur = pCur->_PNext; } return count;} //检测链表是否为空int SListEmpty(SList* s) { if (s->_pHead == NULL) { return -1; } return 0;}//清空链表void SListClear(SList* s) { if (s->_pHead == NULL) { return; } PNode pCur = s->_pHead; while (pCur->_PNext) { //循环清空链表中的节点 PNode Tmp = pCur->_PNext; free(pCur); pCur = Tmp; } if (pCur) { //清空最后一个节点 free(pCur); pCur = NULL; }} //销毁链表void SListDestroy(SList* s) { if (s->_pHead == NULL) { free(s->_pHead); return; } while (s->_pHead) { PNode Tmp = s->_pHead->_PNext; free(s->_pHead); s->_pHead = Tmp; }} //打印链表void SListPrint(SList* s) { PNode pCur = s->_pHead; while (pCur) { printf("%d--->", pCur->_data); pCur = pCur->_PNext; } printf("\n");}/**********************Tests**************************************void main() { SList s; SListInit(&s); SListPushBack(&s, 1); SListPushBack(&s, 2); SListPushBack(&s, 3); printf("size=%d\n", SListSize(&s)); SListPrint(&s); SListInsert(SListFind(&s, 2), 0); SListPrint(&s); SListRemove(&s, 2); SListPrint(&s); system("pause"); return;}*****************************************************************/复制代码 头文件:
#include "gpio.h"
#include <stdio.h>#include <assert.h>#include <stdlib.h>#include <stddef.h>/*人对象的结构体*/typedef struct User{ uint8_t ID; /*用户ID*/ uint8_t cup_ID ; uint8_t locker_index;}stUser;typedef int SDataType;//链表的节点typedef struct SListNode{ SDataType _data; struct SListNode* _PNext;}Node,*PNode;typedef struct SList //封装了链表的结构{ PNode _pHead;//指向链表第一个节点}SList;void SListInit(SList*s);//链表的初始化//在链表s最后一个节点后插入一个值为data的节点void SListPushBack(SList* s, SDataType data);//删除链表s最后一个节点void SListPopBack(SList* s);//在链表s第一个节点前插入值为data的节点void SListPushFront(SList* s, SDataType data);//删除链表s的第一个节点void SListPopFront(SList* s);//在链表的pos位置后插入值为data的节点void SListInsert(PNode pos, SDataType data);//删除链表s中pos位置的节点void SListErase(SList* s, PNode pos);// 在链表中查找值为data的节点,找到返回该节点的地址,否则返回NULL PNode SListFind(SList* s, SDataType data);//移除链表中第一个值为data的元素void SListRemove(SList*s, SDataType data);// 获取链表中有效节点的个数 int SListSize(SList* s);// 检测链表是否为空 int SListEmpty(SList* s);// 将链表中有效节点清空 void SListClear(SList* s);// 销毁链表 void SListDestroy(SList* s);//打印链表void SListPrint(SList* s);复制代码