链表功能
结构简单,一般不会单独用来存数据。实际中更多是作为其他数据结构的子结构,如哈希桶、图的邻接表等等。
文件分装
对应文件的代码
SList.h
#pragma once //需要用到的库函数的头文件 #include<stdio.h> #include<stdlib.h> //链表数类型的重定义 typedef int SLTDateType; //链表节点的声明 typedef struct SListNode { SLTDateType data; struct SListNode* next; }SListNode; // 单链表打印 void SListPrint(SListNode* plist); // 单链表尾插 void SListPushBack(SListNode** pplist, SLTDateType x); // 单链表的头插 void SListPushFront(SListNode** pplist, SLTDateType x); // 单链表的尾删 void SListPopBack(SListNode** pplist); // 单链表头删 void SListPopFront(SListNode** pplist); // 单链表查找 SListNode* SListFind(SListNode* plist, SLTDateType x); // 单链表在pos位置之后插入x //PS:不在pos位置插入的原因:单链表不方便找到pos位置之前的节点,从而实现新节点和前面节点的相连 void SListInsertAfter(SListNode* pos, SLTDateType x); // 单链表删除pos位置之后的值 //PS:不在pos位置删除的原因:单链表不方便找到pos位置之前的节点,从而实现前后节点的相连 void SListEraseAfter(SListNode* pos); // 单链表的销毁 void Destory(SListNode** pplist);
SList.c
#include"SList.h" // 动态申请一个节点 static SListNode* BuySListNode(SLTDateType x) { SListNode* newnode = (SListNode*)malloc(sizeof(SListNode)); newnode->data = x; newnode->next = NULL; //最后把申请出来的节点返回 return newnode; } // 单链表打印 void SListPrint(SListNode* plist) { //PS:若链表为空直接打印NULL while (plist) { printf("%d->", plist->data); plist = plist->next; } printf("NULL\n"); } // 单链表尾插 void SListPushBack(SListNode** pplist, SLTDateType x) { //开辟一个新节点 SListNode* newnode = BuySListNode(x); SListNode* cur = *pplist; // 1.空链表的情况 if (!cur) { *pplist = newnode; } // 2.非空链表的情况 else { //寻找尾节点 while (cur->next) { cur = cur->next; } cur->next = newnode; } } // 单链表的头插 void SListPushFront(SListNode** pplist, SLTDateType x) { SListNode* newnode = BuySListNode(x); //使新节点的next指向原来的第一个结点 newnode->next = *pplist; //新节点为链表的第一个节点 *pplist = newnode; } // 单链表的尾删 void SListPopBack(SListNode** pplist) { SListNode* pre = NULL;//当前节点的前一个节点 SListNode* cur = *pplist;//当前节点 // 1.空链表的情况 if (!cur) { return; } // 2.非空链表的情况 //寻找尾节点 while (cur->next) { pre = cur; cur = cur->next; } // 2.1只有一个节点的情况 if (!pre) { free(*pplist); *pplist = NULL; return; } // 2.2有两个及以上节点的情况 pre->next = NULL; free(cur); cur = NULL; } // 单链表头删 void SListPopFront(SListNode** pplist) { // 1.空链表的情况 if (!(*pplist)) { return; } // 2.非空链表的情况 SListNode* next = (*pplist)->next; free(*pplist); *pplist = next; } // 单链表查找 //PS:修改的话由使用者查找到节点之后自己修改就行 SListNode* SListFind(SListNode* plist, SLTDateType x) { //遍历链表 while (plist) { if (plist->data == x) { return plist; } plist = plist->next; } //空链表或者找不到就返回NULL return NULL; } // 单链表在pos位置之后插入x void SListInsertAfter(SListNode* pos, SLTDateType x) { SListNode* newnode = (SListNode*)BuySListNode(x); // 1.空链表的情况 if (!pos) { return; } // 2.非空链表的情况 else { newnode->next = pos->next; pos->next = newnode; } } // 单链表删除pos位置之后的值 void SListEraseAfter(SListNode* pos) { //空链表的情况 if (!pos) { return; } //非空链表的情况 SListNode* next = pos->next; //若pos之后还有节点就删除 //没有的话就啥都不干 if (next) { pos->next = next->next; free(next); next = NULL; } } // 单链表的销毁 void Destory(SListNode** pplist) { SListNode* cur=*pplist; while(cur) { SLitsNOde* next=cur->next; free(cur); cur=next; } *pplist=NULL; }
test.c
#include"SList.h" int main() { //测试 SListNode* p = NULL; SListPushBack(&p, 1); SListPushBack(&p, 2); SListPushBack(&p, 3); SListEraseAfter(p); SListEraseAfter(p); SListPrint(p); Destory(&p); return 0; }