4.尾删:删除单链表尾部的最后一个结点
void SListPopBack(SLTNode** pplist) { if (*pplist == NULL) { return; } else if ((*pplist)->next == NULL) { free(*pplist); *pplist = NULL; } else { SLTNode* prev = NULL; SLTNode* tail = *pplist; while (tail->next != NULL) { prev = tail; tail = tail->next; } free(tail); tail = NULL; prev->next = NULL; } }
5.头插:在存储第一个元素的结点前插入一个结点
void SListPushFront(SLTNode** pplist, SLTDataType x) { SLTNode* newnode = BuySLTNode(x); newnode->next = *pplist; *pplist = newnode; }
6.头删:删除存储第一个元素的结点
void SListPopFront(SLTNode** pplist) { if (*pplist == NULL) { return; } else { SLTNode* next = (*pplist)->next; free(*pplist); *pplist = next; } }
7.在pos结点后插入一个结点
void SListInsertAfter(SLTNode* pos, SLTDataType x) { assert(pos); SLTNode* newnode = BuySLTNode(x); newnode->next = pos->next; pos->next = newnode; }
8.在pos结点后删除一个结点
void SListEraseAfter(SLTNode* pos) { assert(pos); if (pos->next == NULL) { return; } else { SLTNode* next = pos->next; pos->next = next->next; free(next); } }
SLTNode* SListFind(SLTNode* plist, SLTDataType x) { SLTNode* cur = plist; while (cur) { if (cur->data == x) { return cur; } cur = cur->next; } return NULL; }
10.单链表的销毁
void SLTNodeDestory(SLTNode** pphead) { SLTNode* cur=*pphead; while(cur) { SLTNode* next=cur->next; free(cur); cur=next; } }
有小伙伴看到这里就可能会问了,为什么单链表的接口这里没有单链表的初始化,那是因为,单链表的初始化和销毁也就是对头指针进行操作,那个一步就能完成,所以在主函数里面就可以完成,可以但没必要创建一个专门的接口去处理。
另外插一句,单链表的头很重要,
例一:如果要想清空一个结点,只用phead=NULL即可,只要头指针还在,队伍还可以重新拉起来,只要青山在,不怕没柴烧;但是要销毁单链表则需要将头指针free掉,这样这个单链表才真正的out了。
例二:只要找到了头指针,就可拉起整个单链表,遍历就可以找到每一个结点。(这就是为什么在一些操作时要始终秉承这不能修改phead这个原则的原因)
小小实战:
请写用无头单链表依次尾插五个数1,2,3,4,5,并且删掉2这个数,并将删除后的链表反转,(暂时还不会写的话合理利用到上面的接口实现哦,相信你能独立写出来)
反转:
before:1-->2-->3-->4-->5-->NULL;
after:5-->4-->3-->2-->1-->NULL;
代码参考:
#define _CRT_SECURE_NO_WARNINGS 1 #include<stdio.h> #include<stdlib.h> typedef struct SLTNode { int date; struct SLTNode* next; }SLTNode; SLTNode* BuySLTNode(int e) { SLTNode* newnode = (SLTNode*)malloc(sizeof(SLTNode)); newnode->date = e; newnode->next = NULL; return newnode; } void SLTNodePushBack(SLTNode** pphead, int e) { SLTNode* newnode = BuySLTNode(e); if (*pphead == NULL) { *pphead = newnode; } else { SLTNode* tail = *pphead; //尾插找尾 while (tail->next != NULL) { tail = tail->next; } tail->next = newnode; } } void SLTNodePrint(SLTNode* phead) { SLTNode* cur = phead; while (cur != NULL) { printf("%d->", cur->date); cur = cur->next; } printf("NULL"); printf("\n"); } SLTNode* SLTNodeFind(SLTNode* phead, int n) { SLTNode* cur = phead; for (int i = 0; i < n; i++) { cur = cur->next; } return cur; } void SLTNodeErase(SLTNode** pphead, SLTNode* pos) { SLTNode* prev = *pphead; while (prev->next != pos) { prev = prev->next; } prev->next = pos->next; free(pos); } SLTNode* SLT_Reverse(SLTNode* phead) { SLTNode* newphead = NULL; SLTNode* cur = phead; while (cur) { SLTNode* next = cur->next; cur->next = newphead; newphead = cur; cur = next; } return newphead; } int main() { SLTNode* phead = NULL; SLTNodePushBack(&phead, 1); SLTNodePushBack(&phead, 2); SLTNodePushBack(&phead, 3); SLTNodePushBack(&phead, 4); SLTNodePushBack(&phead, 5); SLTNodePrint(phead); SLTNode* pos=SLTNodeFind(phead, 1); SLTNodeErase(&phead, pos); SLTNodePrint(phead); SLTNode* newphead=SLT_Reverse(phead); SLTNodePrint(newphead); return 0; }
打印结果: