欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 财经 > 创投人物 > 数据结构---顺序表之单链表

数据结构---顺序表之单链表

2024/10/25 13:30:22 来源:https://blog.csdn.net/bite_free/article/details/142490623  浏览:    关键词:数据结构---顺序表之单链表

1.链表的概念

链表是一种逻辑上是线性的,但物理结构不一定是线性的数据结构,它通过链表中的指针链接次序实现的

链表的存储空间是我们通过动态内存开辟的内存空间,所以他们的地址可能是连续的也可能不是连续的

2.链表的分类

1.单向或者双向

2.带头或者不带头

3.循环或者不循环

虽然链表有这么多种类,单我们常用的就只有两种:

                                               单向不带头不循环链表(单链表)

                                                   双向带头循环链表(双链表)

3.单链表的实现

SList.h

// 1、无头+单向+非循环链表增删查改实现
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
// 分析思考为什么不在pos位置之前插入?
void SListInsertAfter(SListNode* pos, SLTDateType x);
// 单链表删除pos位置之后的值
// 分析思考为什么不删除pos位置?
void SListEraseAfter(SListNode* pos);

SList.c

//为什么这里要用二级指针?
//因为我们的头结点是一个结构体指针,我们可能会改变头结点,所以我们需要传结构体地址的地址// 动态申请一个结点
SListNode* BuySListNode(SLTDateType x) {SListNode* NewNode = (SListNode*)malloc(sizeof(SListNode));if (NewNode == NULL) {return 0;}NewNode->next = NULL;NewNode->data = x;return NewNode;
}
// 单链表打印
void SListPrint(SListNode* plist) {SListNode* pcur = plist;while (pcur) {printf("%d->", pcur->data);pcur = pcur->next;}printf("NULL\n");
}
// 单链表尾插
void SListPushBack(SListNode** pplist, SLTDateType x) {assert(pplist);SListNode* NewNode = BuySListNode(x);//如果链表为NULL,头结点就是NewNodeif (*pplist == NULL) {*pplist = NewNode;return;}//链表不为NULL,找到尾节点插入SListNode* pcur = *pplist;while (pcur->next) {pcur = pcur->next;}pcur->next = NewNode;
}
// 单链表的头插
void SListPushFront(SListNode** pplist, SLTDateType x) {assert(pplist);SListNode* NewNode = BuySListNode(x);SListNode* pcur = *pplist;NewNode->next = pcur;*pplist = NewNode;
}
// 单链表的尾删
void SListPopBack(SListNode** pplist) {assert(pplist);//链表为NULL不能执行删除assert(*pplist);//如果链表只有1个节点if ((*pplist)->next == NULL) {free(*pplist);*pplist = NULL;return;}SListNode* pcur = *pplist;SListNode* prev = NULL;while (pcur->next) {prev = pcur;pcur = pcur->next;}prev->next = pcur->next;free(pcur);pcur = NULL;
}
// 单链表头删
void SListPopFront(SListNode** pplist) {assert(pplist);assert(*pplist);SListNode* pcur = *pplist;*pplist = pcur->next;free(pcur);pcur = NULL;}
// 单链表查找
SListNode* SListFind(SListNode* plist, SLTDateType x) {assert(plist);SListNode* pcur = plist;while (pcur) {if (pcur->data == x) {return pcur;}pcur = pcur->next;}//未找到返回NULLreturn NULL;
}
// 单链表在pos位置之后插入x
// 分析思考为什么不在pos位置之前插入?
//因为单链表的节点只能找后继结点,不能找前驱
void SListInsertAfter(SListNode* pos, SLTDateType x) {assert(pos);SListNode* NewNode = BuySListNode(x);NewNode->next = pos->next;pos->next = NewNode;
}
// 单链表删除pos位置之后的值
// 分析思考为什么不删除pos位置?
// 如果链表存在多个节点,pos节点之前的节点就会丢失,造成内存泄露
void SListEraseAfter(SListNode* pos) {assert(pos);assert(pos->next);SListNode* DeleNode = pos->next;pos->next = DeleNode->next;free(DeleNode);DeleNode = NULL;
}

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com