这篇文章将为大家详细讲解有关C语言中单链表怎么用,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。1、单链表概念:链表是一种物理存储结构上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序
这篇文章将为大家详细讲解有关C语言中单链表怎么用,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。
概念:链表是一种物理存储结构上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的 。
(链表和我们生活中最接近的就是火车了。)
接下来我们来实现单链表的增删查改
#pragma once #include <stdio.h>#include <assert.h>#include <stdlib.h> typedef int SLDataType; //链表的创建typedef struct SListnode{SLDataType data;//valstruct SListNode* next;//存储下一个结点的地址}SListNode,SLN; //打印链表void SListPrint(SListNode* phead); //尾插void SListPushBack(SListNode** pphead, SLDataType x); //头插void SListPushFront(SListNode** pphead, SLDataType x); //尾删void SListPopBack(SListNode** pphead); //头删void SListPopFront(SListNode** pphead); //查找SListNode* SListFind(SListNode* phead, SLDataType x); //在pos位置之前插入void SListInsert(SListNode** pphead, SListNode* pos, SLDataType x); //删除pos位置void SListErase(SListNode** pphead, SListNode* pos); //在pos位置之后插入void SlistInserAfter(SListNode* pos, SLDataType x); //删除pos后的值void SlistEraseAfter(SListNode* pos); //用完销毁void SListDestroy(SListNode** pphead);
void SListPrint(SListNode* phead){assert(phead); SListNode* cur = phead; if (cur == NULL){printf("SList is NULL\n");} while (cur != NULL){printf("%d->", cur->data);cur = cur->next;}printf("NULL\n");}
将一个data x动态申请结点。
SListNode* BuySList(SLDataType x){SListNode* newnode = (SListNode*)malloc(sizeof(SListNode));if (newnode == NULL){printf("malloc fail\n");exit(-1);}else{newnode->data = x;newnode->next = NULL;}return newnode;}
void SListPushBack(SListNode** pphead, SLDataType x){assert(pphead); SListNode* newnode = BuySList(x);if (*pphead == NULL){*pphead = newnode;}else{//找尾SListNode* tail = *pphead;while (tail->next != NULL){tail = tail->next;}//走完循环找到尾tail->next = newnode;} }
void SListPushFront(SListNode** pphead, SLDataType x){assert(pphead); SListNode* newnode = BuySList(x); newnode->next = *pphead;*pphead = newnode; }
void SListPopBack(SListNode** pphead){assert(pphead); //当链表只有一个结点时if (*pphead == NULL){printf("SListNode is NULL\n");return;}//当链表只有一个结点时else if ((*pphead)->next == NULL){free(*pphead);*pphead = NULL;}//当链表有多个结点时else{SListNode* tail = *pphead;while (tail->next->next != NULL){tail = tail->next;}free(tail->next);tail->next = NULL;}}
void SListPopFront(SListNode** pphead){assert(pphead); if (*pphead == NULL){printf("SList is NULL\n");return;}else{SListNode* next = (*pphead)->next;free(*pphead);*pphead = next;}}
SListNode* SListFind(SListNode* phead, SLDataType x){assert(phead); SListNode* cur = phead;while (cur != NULL){if (cur->data == x){return cur;}//如果没找到就往下走cur = cur->next;}//循环完成后还没找到就说明链表中没有该值return NULL;}
void SListInsert(SListNode** pphead, SListNode* pos, SLDataType x){assert(pphead);assert(pos); //pos是第一个位置if (pos == *pphead){SListPushFront(pphead, x);} //pos不是第一个位置else{SListNode* prev = *pphead;while (prev->next != pos){prev = prev->next;}SListNode* newnode = BuySList(x);prev->next = newnode;newnode->next = pos;}}
void SListErase(SListNode** pphead, SListNode* pos){assert(pphead);assert(pos); //1、头结点为空if (*pphead == NULL){printf("SList is NULL\n");return;}//2、删除第一个结点else if (pos == *pphead){SListPopFront(pphead);}//3、其他结点else{SListNode* prev = *pphead;while (prev->next != pos){prev = prev->next;}prev->next = pos->next;free(pos);pos = NULL;}}
相对于在pos之前插入,在pos后插入可以不用传头结点,无论pos在哪个位置都适用。
void SListInsertAfter(SListNode* pos, SLDataType x){assert(pos); SListNode* newnode = BuySList(x);SListNode* next = pos->next; pos->next = newnode;newnode->next = next; //下面这种方式也可以}
void SListEraseAfter(SListNode* pos){assert(pos); SListNode* next = pos->next;if (next){pos->next = next->next;free(next);next = NULL;}}
void SListDestroy(SListNode** pphead){assert(pphead); SListNode* cur = *pphead;while (cur){SListNode* next = cur->next;free(cur);cur = next;} *pphead = NULL;}
#include "SList.h" void test1(){SListNode* slist = NULL; //测试尾插SListPushBack(&slist, 1);SListPushBack(&slist, 2);SListPushBack(&slist, 3);SListPushFront(&slist, 5);SListPushFront(&slist, 4);SListPrint(slist); //测试头插SListPushFront(&slist, 5);SListPushFront(&slist, 4);SListPrint(slist); //测试尾删SListPopBack(&slist);SListPopBack(&slist);SListPrint(slist); //测试头删SListPopFront(&slist);SListPopFront(&slist);SListPopFront(&slist);SListPrint(slist); //测试查找SListNode* ret1 = SListFind(slist, 5);printf("%d\n", ret1->data); //pos前插测试SListNode* pos = SListFind(slist, 1);if (pos){SListInsert(&slist,pos,3);}SListPrint(slist);pos = SListFind(slist, 1);if (pos){SListInsert(&slist, pos, 10);}SListPrint(slist); //删除pos测试pos = SListFind(slist, 10);if (pos){SListErase(&slist, pos);}SListPrint(slist); //测试在pos后插入pos = SListFind(slist, 3);if (pos){SListInsertAfter(pos, 6);}SListPrint(slist);pos = SListFind(slist, 1);if (pos){SListInsertAfter(pos, 8);}SListPrint(slist); //测试删除pos后的值pos = SListFind(slist, 1);if (pos){SListEraseAfter(pos);}SListPrint(slist); } int main(){test1(); return 0;}
运行结果:
单链表的实现到此结束,如果你还想更进一步,请关注后续----单链表OJ,让你从此不再迷茫!
关于“C语言中单链表怎么用”这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,使各位可以学到更多知识,如果觉得文章不错,请把它分享出去让更多的人看到。
--结束END--
本文标题: C语言中单链表怎么用
本文链接: https://www.lsjlt.com/news/325659.html(转载时请注明来源链接)
有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341
下载Word文档到电脑,方便收藏和打印~
2024-03-01
2024-03-01
2024-02-29
2024-02-29
2024-02-29
2024-02-29
2024-02-29
2024-02-29
2024-02-29
2024-02-29
回答
回答
回答
回答
回答
回答
回答
回答
回答
回答
0