-
单链表概念讲解
单链表通过一组任意的存储单元来存储线性表中的数据元素,不需要使用地址连续的存储单元。
单链表形式:两个储存空间,一个储存数据(值域),一个储存下一个节点的地址(指针域)。
-
单链表形式创建
要想实现以上功能,需要建立结构体,其中包含储存数据的变量和储存地址的变量
这里的类型可以用typedef来定义变量,使其具有普遍性。
代码如下
typedef int STLDatatype;
typedef struct SListnode
{
STLDatatype data;
struct SListnode* next;
}SListnode; //定义结构体名称
链表的基本形式创建后,我们就可以实现链表的增删查改等等的接口。
在此之前,先实现链表的基本功能:打印。
-
单链表打印
单链表打印非常简单,只需循环遍历,去访问每一个元素即可
void SListPrint(SListnode* phead)//形参为结构体类型的指针
{
SListnode* cur = phead;//避免phead被改变,用cur指针变量进行操作
//phead为结构体首地址
while (cur != NULL)
{
printf("%d->", cur->data);//结构体内容访问
cur = cur->next;
}
printf("NULL\n");
}
以此实现的打印
-
单链表头插尾插
注意到无论在头部插入元素还是在尾部插入元素,我们都需要向内存申请一块空间,来储存数据,进而我们首先要实现内存开辟的功能并且实现数据的写入。
单链表的内存开辟
SListnode* BuySListnode(STLDatatype x)//x为写入的数据
{
SListnode* newnode = (SListnode*)malloc(sizeof(SListnode));
newnode->data = x;//数据写入
newnode->next = NULL;//在此节点设为null
return newnode;
}
说明:
定义一个函数BuySListnode,函数返回值为结构体指针SListnode*(先前用typedef定义的类型)
参数为STLDatatype类型的数据x,用malloc 开辟空间,返回值为一个地址用newnode接收。
单链表头插
说明:
首先要改变头指针(plist),使其指向新增节点的首地址,需要用二级指针改变plist指针的内容
void SListPushfront(SListnode** plist, STLDatatype x)
{
SListnode* newnode = BuySListnode(x);
newnode->next = *plist; //将原来的头部节点地址赋值给新节点next
*plist = newnode; //改变头指针指向新增链表地址
}
单链表尾插
代码如下
void SListPushback(SListnode** plist, STLDatatype x)
{
SListnode* newnode = BuySListnode(x);
SListnode* ret = *plist;
if (*plist == NULL)
{
*plist = newnode;
}
else
{
while (ret->next != NULL)
{
ret = ret->next;
}
ret->next = newnode;
}
}//头插
-
单链表头删
说明:需改变头指针指向内容,和释放第一个节点。
void SListPopfront(SListnode** plist)
{
if (*plist == NULL)//没有节点时,不需任何处理
{
return;
}
else
{
SListnode* head = (*plist)->next;
free(*plist);
*plist = head;
}
}
-
单链表尾删
尾删步骤:
首先找到要删除最后节点的前一个节点,将前一个节点的next赋值为null,再释放最后一个节点。
找到要删除最后节点的前一个节点方法,采用前后指针法,前后指针相差一个单位,当后指针在最后一节点停下时,前指针在停下节点的前一个节点停下。
void SListPopback(SListnode** plist)
{
if (*plist == NULL)//没有节点时
{
return;
}
else if ((*plist)->next == NULL) //只有一个节点时
{
free(*plist);
*plist = NULL;
}
else //两个及两个以上节点
{
SListnode* front = NULL;
SListnode* tail = *plist;
while (tail->next != NULL)//前后指针
{
front = tail;
tail = tail->next;
}
free(tail);
front->next = NULL;
}
}
注意if,与else if的特殊情况
若if的情况(没有节点时)时走else的代码
若else if的情况(有一个节点时)时走else的代码
好了,单链表上的基本功能已经实现好了,若文章有错误的地方,欢迎各位来指正。