你好,我是史丰源
欢迎你的来访,希望我的博客能给你带来一些帮助。
我的Gitee:代码仓库.☀️
我的联系方式:
QQ:1756786195
邮箱:Marksky126@outlook.com🌐
今天我们来学习 单链表的增删查改
单链表(无头单向非循环链表)
简介:单链表一般不会单独存储数据,而是为今后学习的其他数据结构打基础
单链表结构
typedef int SLTDateType;//为方便日后更改数据类型
typedef struct SListNode//单链表的结点
{
SLTDateType data;//单链表中的数据域
struct SListNode* next;//单链表中的指针域
}SLTNode;
单链表创建新结点
SLTNode* BuySListNode(SLTDateType x)
{
SLTNode* newnode = (SLTNode*)malloc(sizeof(SLTNode*));
assert(newnode);
newnode->data = x;
newnode->next = NULL;
return newnode;
}
封装成一个函数是为了今后调用很方便,在工程开发中,经常用到。
单链表打印
void SListPrint(SLTNode* phead)
{
SLTNode* cur = phead;
while (cur)
{
printf("%d ", cur->data);
cur = cur->next;
}
}
单链表的尾插
链表不为空的情况:先去找到链表的最后一个空间,这个空间的next原本指NULL,但我们要插入进去,就要链接,所以next指针改向指newnode.newnode->next 指向NULL
链表为空:直接将新的结点作为(赋值)给头结点。
void SListPushBack(SLTNode** pphead, SLTDateType x)
{
SLTNode* tail = *pphead;
SLTNode* newnode = BuySListNode(x);
if (*pphead = NULL)
{
*pphead = newnode;
}
while (tail->next!=NULL)//找尾
{
tail = tail->next;
}
tail->next = newnode;
}
单链表的尾删
多个结点的情况:先去找尾,找尾的同时也用prev指针标记尾的前一个空间,prev的next原本指tail,现在要释放尾,prev的next就指向NULL。
一个结点的情况:直接释放头结点,并且置空。
void SListPopBack(SLTNode** pphead)
{
if ((*pphead)->next == NULL)//只有一个结点的情况
{
free(*pphead);
*pphead= NULL;
}
else//多个结点
{
SLTNode* tailprev = NULL;
SLTNode* tail = *pphead;
while (tail->next != NULL)
{
tailprev = tail;//保存tail的前一个空间
tail = tail->next;
}
free(tail);
tailprev->next = NULL;
}
}
单链表头插
头插头删是单链表比顺序表效率高的地方,直接将新的结点链接在头结点前。
将新结点的next链接到头结点,然后将头结点的位置移到新的结点上。
void SListPushFront(SLTNode** pphead, SLTDateType x)
{
SLTNode* newnode = BuySListNode(x);
if (*pphead = NULL)
{
*pphead = newnode;
}
newnode->next = *pphead;//链接到头结点
*pphead = newnode;//头结点的新位置就是新结点
}
单链表的头删
先保存头结点的下一个结点,然后释放头结点,将头结点的位置移向下一个空间
void SListPopFront(SLTNode** pphead)
{
SLTNode* next = (*pphead)->next;
free(*pphead);
*pphead = next;
}