前言
今天是我加入csdn的第336天,当然要写一篇博客记录一下~ 想起最开始注册博客是为了复制代码完成学校作业,后来搁置了大半年,最近4,5个月才使用频繁一点。准备坚持多写一点也算巩固自身!✨✨✨
言归正传,我们说单链表。
链表是一种链式存取的数据结构,通过指针将一个个零散的内存块连接起来,用一组地址任意的存储单元存放线性表中的数据元素。每个结点只有一个链域的链表称为单链表。
一、单链表的初始化和打印
这里要大量用到C语言的结构体,大家结构体不太熟悉的可以先去熟悉一些结构体相关知识哦😘
//定义单链表结构
#include <stdio.h>
typedef int SLTDateType;
typedef struct SListNode
{
SLTDateType data;
struct SListNode* next;
}SListNode;
//初始化,创建头结点,动态申请一个节点
SListNode* BuySListNode(SLTDateType x)
{
SListNode* node = (SListNode*)malloc(sizeof(SListNode));
node->data = x;
node->next = NULL;
return node;
}
// 单链表打印
void SListPrint(SListNode* plist)
{
SListNode* cur = plist;//头结点
while (cur)
{
printf("%d->", cur->data);
cur = cur->next;
}
printf("NULL\n");
}
下面来看打印结果
二、增删查改
1.尾插头插
// 单链表尾插
void SListPushBack(SListNode** pplist, SLTDateType x)
{
SListNode* newnode = BuySListNode(x);//调用上面的函数
if (*pplist == NULL)
{
*pplist = newnode;
}
else
{
SListNode* tail = *pplist;
while (*pplist != NULL)
{
tail = tail->next;
}
tail->next = newnode;
}
}
// 单链表的头插
void SListPushFront(SListNode** pplist, SLTDateType x)
{
assert(pplist);
SListNode* newnode = BuySListNode(x);
if (*pplist == NULL)
{
*pplist = newnode;
}
else
{
newnode->next = *pplist;
*pplist = newnode;
}
}
2.尾删头删
// 单链表的尾删
void SListPopBack(SListNode** pplist)
{
SListNode* prev = NULL;
SListNode* tail = *pplist;
if (tail == NULL || tail->next == NULL)
{
free(tail);
*pplist = NULL;
}
else
{
while (tail->next)
{
prev = tail;
tail = tail->next;
}
free(tail);
tail = NULL;
prev->next = NULL;
}
}
// 单链表头删
void SListPopFront(SListNode** pplist)
{
SListNode* first = *pplist;
if (first == NULL)
{
return;
}
else if (first->next == NULL)
{
free(first);
*pplist = NULL;
}
else
{
SListNode* next = first->next;
free(first);
*pplist = next;
}
}
这里要说的一点是:只要改变plist,就要传plist的地址,就需要二级指针
3.指定位置的增删
// 单链表查找
SListNode* SListFind(SListNode* plist, SLTDateType x)
{
SListNode* cur = plist;
while (cur)
{
if (cur->data == x)
return cur;
cur = cur->next;
}
return NULL;
}
// 单链表在pos位置之后插入x
void SListInsertAfter(SListNode* pos, SLTDateType x)
{
assert(pos);
SListNode* next = pos->next;
// pos newnode next
SListNode* newnode = BuySListNode(x);
pos->next = newnode;
newnode->next = next;
}
// 单链表删除pos位置之后的值
void SListEraseAfter(SListNode* pos)
{
assert(pos);
// pos next nextnext
SListNode* next = pos->next;
if (next != NULL)
{
SListNode* nextnext = next->next;
free(next);
pos->next = nextnext;
}
}
// 单链表的销毁
void SListDestory(SListNode* plist)
{
free(plist->next);
plist->next=NULL;
plist->data = 0;
}
补充:这里的指定位置添加和删除是可以用到头插尾 插头删尾删的
只是这里我们写头删头插这些更加理解链表
总结
总之链表还有很多细节,这里就不详细说明了。也可以多写怎么求链表长度,还可以给链表写一个菜单,这些都可以自己有兴趣写一下,以上就是单链表的重要部分了。之后会写一些链表的oj与大家分享~感谢支持,谢谢大家!!!