文章目录
之前讲了顺序表的增删查改,这篇文章我们来讲解比顺序表复杂一些的单链表的增删查改的功能实现。
我们还是将程序分为SLTist.h SLTist.c test.c,函数的实现在 SLTist.c中,声明在SLTist.h中,功能的测试在test.c中
#define _CRT_SECURE_NO_WARNINGS
#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
typedef int SLTdatatype;
typedef struct SLTist
{
SLTdatatype data;
struct SLTist* next;
}SLT;
void PRINTSLT(SLT* ps);//打印
SLT* BuySListNode(SLTdatatype x);//创建新节点
void SLTPushBack(SLT** phead, SLTdatatype x);//尾插
void SLTPushFront(SLT** pphead, SLTdatatype x);//头 插
void SLTPopBack(SLT* *pphead);//尾删
void SLTPopFront(SLT** pphead);//头删
SLT* SListFind(SLT* plist, SLTdatatype x);// 单链表查找
void SListInsertAfter(SLT* pos, SLTdatatype x);// 单链表在pos位置之后插入x
void SLTErase(SLT** pphead, SLT* pos);// 删除pos位置
void SLTEraseAfter(SLT* pos);// 删除pos的后一个位置
首先创建一个结构体,两个成员分别是数据和下一个节点的指针.
下面我们就来依次实现每一个功能:
void PRINTSLT(SLT* ps)
{
SLT* cur = ps;
while (cur != NULL)
{
printf("%d->", cur->data);
cur = cur->next;
}
printf("NULL\n");//打印
}
SLT* BuySListNode(SLTdatatype x)
{
SLT*NEWNODE=(SLT*)malloc(sizeof(SLT));
if (NEWNODE == NULL)
{
perror("malloc failed");
exit(-1);
}
NEWNODE->data=x;
NEWNODE->next = NULL;
return NEWNODE;//创建新节点
}
void SLTPushBack(SLT**phead, SLTdatatype x)
{
SLT* NEWNODE = BuySListNode(x);
SLT* tail = *phead;
if(*phead==NULL)
{
*phead = NEWNODE;
}
else
{
while (tail->next != NULL)
{
tail = tail->next;
}
tail->next = NEWNODE;
}
}//尾插
尾插这里注意单链表如果一个节点都没有的情况.
void SLTPushFront(SLT** pphead, SLTdatatype x)
{
SLT*NEWNODE= BuySListNode(x);
NEWNODE->next = *pphead;
*pphead = NEWNODE;
}//头插
这里要注意两个点,因为是头插,我们需要改变第一个指针的内容,所以我们需要用二级指针来接收(之后在实现其他功能的时候如果需要该改变头指针地址,都需要用二级指针来接收),第二个点:要先把头指针的传给新节点,再把新节点的地址给头指针,如果顺序反了,头指针就会被覆盖,找不到下一个节点了。
void SLTPopBack(SLT**pphead)
{
//没有节点:
assert(*pphead);
SLT*tail = *pphead;
//只剩下一个节点
if ((*pphead)->next==NULL)
{
free(*pphead);
*pphead = NULL;
}
else//不止一个节点
{
while (tail->next->next != NULL)
{
tail = tail->next;
}
free(tail->next);
tail ->next= NULL;
}
}//尾删
void SLTPopFront(SLT** pphead)
{
//assert(pphead);//没有节点
assert(*pphead);//有节点
SLT* tail = (*pphead)->next;
free(*pphead);
*pphead = tail;
}//头删
SLT* SListFind(SLT* plist, SLTdatatype x)
{
assert(plist);
while (plist->data != x)
{
plist = plist->next;
}
return plist;
}//找节点
void SListInsertAfter(SLT* pos, SLTdatatype x)
{
assert(pos);
SLT*NEWNODE=BuySListNode(x);
NEWNODE->next = pos->next;
pos->next = NEWNODE;
}//单链表在pos位置之后插入x
这里也要注意赋值的顺序
void SLTErase(SLT** pphead, SLT* pos)
{
assert(*pphead);
//头删
if (pos == *pphead)
{
SLTPopFront(pos);
}
//不在头的位置
else
{
SLT* tail = *pphead;
while (tail->next != pos)
{
tail = tail->next;
}
tail->next = pos->next;
free(pos);
}
}//删除pos位置
void SLTEraseAfter(SLT* pos)
{
assert(pos);
if (pos->next == NULL)
{
exit(-1);
}
else
{
SLT* PS = pos->next;
pos->next = pos->next->next;
free(PS);
}
}//删除pos的后一个位置
以上就是有关单链表一些功能的实现,如有错误,欢迎指正,谢谢大家!