2.7 单链表的头插
1.void SListPushFront(SListNode** pplist, SLTDateType x) { assert(pplist); SListNode* newnode = BuySListNode(x); newnode->next = *pplist; *pplist = newnode; }
对于头插这里我们进行的操作就比较简单了,首先向内存创建一个节点,然后新节点的next指向头节点,然后把头指针指向新节点,具体如下:
第一步:
第二步:
测试如下:
void text2() { SListNode* s = NULL; SListPushFront(&s, 1); SListPushFront(&s, 2); SListPushFront(&s, 3); SListPushFront(&s, 4); SListPrint(s); } int main() { text2(); return 0; }
结果如下:
2.8 单链表头删
void SListPopFront(SListNode** pplist) { assert(pplist); assert(*pplist); SListNode* first = *pplist; *pplist = first->next; free(first); first = NULL; }
对于头删,这里我们需要用一个指针记录头节点位置,然后把头指针指向头节点的下一个节点,然后把头节点释放了即可,具体如下:
这样我们就完成了头删。
测试如下:
void text2() { SListNode* s = NULL; SListPushFront(&s, 1); SListPushFront(&s, 2); SListPushFront(&s, 3); SListPushFront(&s, 4); SListPrint(s); SListPopFront(&s); SListPrint(s); SListPopFront(&s); SListPrint(s); } int main() { text2(); return 0; }
结果如下:
2.9 单链表查找
SListNode* SListFind(SListNode* plist, SLTDateType x) { if (plist == NULL) { return NULL; } SListNode* dest=plist; while (dest) { if (dest->data == x) { return dest; } dest = dest->next; } return NULL; }
这里我们还是以内容查找,思路很简单,就是遍历,找到后返回找到的那个节点,没找到返回空指针即可。由于这里我们不好测试,我们配合下面的在某个位置插入给大家演示。
2.10 单链表在pos位置之后插入x
void SListInsertAfter(SListNode* pos, SLTDateType x) { SListNode* newnode=BuySListNode(x); assert(pos); newnode->next = pos->next; pos->next = newnode; }
这里我们需要配合查找找到需要插入的元素,这里的逻辑也比较简单,我给大家用演示一下
测试如下:
1.void text1() { SListNode* s = NULL; SListPushBack(&s, 1); SListPushBack(&s, 2); SListPushBack(&s, 3); SListPushBack(&s, 4); SListPrint(s); SLTDateType x = 0; scanf("%d", &x); SListNode* pos = SListFind(s, x); SListInsertAfter(pos, 6); SListPrint(s); } int main() { text1(); return 0; }
结果如下:
2.11 单链表删除pos位置之后的值
void SListEraseAfter(SListNode* pos) { if (pos == NULL&&pos->next) { return; } else { SListNode* find; find = pos->next; pos->next = pos->next->next; free(find); find = NULL; } }
首先判断该位置和下一个位置是不是空,为空直接退出程序,这里我们用指针find记录pos下一个节点,然后将pos的next指向下下个节点即可。
具体如下:
测试如下:
1.void text1() { SListNode* s = NULL; SListPushBack(&s, 1); SListPushBack(&s, 2); SListPushBack(&s, 3); SListPushBack(&s, 4); SListPrint(s); SLTDateType x = 0; scanf("%d", &x); SListNode* pos = SListFind(s, x); SListInsertAfter(pos, 6); SListPrint(s); SListNode*pos1= SListFind(s, x); SListEraseAfter(pos1); SListPrint(s); } int main() { text1(); return 0; }
结果如下:
2.12 单链表的销毁
void SListDestroy(SListNode* plist) { SListNode* p = plist; SListNode* q; while (p) { q = p->next; free(p); p = q; } plist = NULL; }
对于销毁操作,我们需要使用双指针,用q记录要销毁节点的下一个,p用来销毁指针,然后不断对链表进行遍历。
总代码
Slist.c #include"slist.h" SListNode* BuySListNode(SLTDateType x) { SListNode* newnode = (SListNode*)malloc(sizeof(SListNode)); if (newnode == NULL) { perror("malloc fail"); return NULL; } newnode->data = x; newnode->next = NULL; return newnode; } void SListPrint(SListNode* plist) { SListNode* cur = plist; while (cur) { printf("%d-> ", cur->data); cur = cur->next; } printf("NULL\n"); } void SListPushBack(SListNode** pplist, SLTDateType x) { assert(pplist); SListNode*newnode= BuySListNode(x); if (*pplist == NULL) { *pplist = newnode; } else { SListNode* tail=*pplist; while (tail->next) { tail = tail->next; } tail->next = newnode; } } void SListPushFront(SListNode** pplist, SLTDateType x) { assert(pplist); SListNode* newnode = BuySListNode(x); newnode->next = *pplist; *pplist = newnode; } void SListPopBack(SListNode** pplist) { assert(pplist); assert(*pplist); if ((*pplist)->next==NULL) { free(*pplist); *pplist = NULL; } else { SListNode* tail = *pplist; while (tail->next->next) { tail = tail->next; } free(tail->next); tail->next = NULL; } } void SListPopFront(SListNode** pplist) { assert(pplist); assert(*pplist); SListNode* first = *pplist; *pplist = first->next; free(first); first = NULL; } SListNode* SListFind(SListNode* plist, SLTDateType x) { if (plist == NULL) { return NULL; } SListNode* dest=plist; while (dest) { if (dest->data == x) { return dest; } dest = dest->next; } return NULL; } void SListInsertAfter(SListNode* pos, SLTDateType x) { SListNode* newnode=BuySListNode(x); assert(pos); newnode->next = pos->next; pos->next = newnode; } void SListEraseAfter(SListNode* pos) { if (pos == NULL&&pos->next) { return; } else { SListNode* find; find = pos->next; pos->next = pos->next->next; free(find); find = NULL; } } void SListDestroy(SListNode* plist) { SListNode* p = plist; SListNode* q; while (p) { q = p->next; free(p); p = q; } plist = NULL; } Slist.h #include<stdio.h> #include<stdlib.h> #include<assert.h> typedef int SLTDateType; typedef struct SListNode { SLTDateType data; struct SListNode* next; }SListNode; // 动态申请一个节点 SListNode* BuySListNode(SLTDateType x); // 单链表打印 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 void SListInsertAfter(SListNode* pos, SLTDateType x); // 单链表删除pos位置之后的值 void SListEraseAfter(SListNode* pos); // 单链表的销毁 void SListDestroy(SListNode* plist); Text.c #include"slist.h" void text3() { SListNode* s = NULL; SListPushBack(&s, 1); SListPushBack(&s, 2); SListPushBack(&s, 3); SListPushBack(&s, 4); SListPrint(s); SListPopBack(&s); SListPopBack(&s); SListPrint(s); } void text2() { SListNode* s = NULL; SListPushFront(&s, 1); SListPushFront(&s, 2); SListPushFront(&s, 3); SListPushFront(&s, 4); SListPrint(s); SListPopFront(&s); SListPrint(s); SListPopFront(&s); SListPrint(s); } void text1() { SListNode* s = NULL; SListPushBack(&s, 1); SListPushBack(&s, 2); SListPushBack(&s, 3); SListPushBack(&s, 4); SListPrint(s); SLTDateType x = 0; scanf("%d", &x); SListNode* pos = SListFind(s, x); SListInsertAfter(pos, 6); SListPrint(s); SListNode*pos1= SListFind(s, x); SListEraseAfter(pos1); SListPrint(s); } int main() { text1(); return 0; }