目录
前言:
之前在刚接触数据结构时学习了顺序表,但是顺序表的修改牵一发而动全身,加个东西减个东西整体地址大多要变动,所以在这之后我们学习了单链表这样操作相对方便一点,同样的对指针要求也麻烦了点
一、基本思路
单链表不用像顺序表一样一次性申请一大堆内存,可以放一个申请一段空间然后用指针链接这些数据的存放顺序便没有要求,操作起来也相对轻松
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
typedef int SLTDateType;
typedef struct SListNode
{
SLTDateType data;
struct SListNode* next;
}SListNode;
与顺序表相同的头文件以及重定义类型,不同的是结构体内容,放了下一个数据所在位置的指针
二、开工
1、增加内容
(1)首先要整个新数据
SListNode* BuySListNode(SLTDateType x)
{
SListNode* new = (SListNode*)malloc(sizeof(SListNode));
if (new == NULL)
{
perror("malloc fail");
return NULL;
}
new->data = x;
new->next = NULL;
return new;
}
返回新数据的地址
(2)头插
void SListPushFront(SListNode** pplist, SLTDateType x) {
SListNode* new= BuySListNode(x);
new->next = *pplist;
*pplist = new;
}
将头改成新的就好,原来的头放在新头的next里
(3)尾插
void SListPushBack(SListNode** pplist, SLTDateType x)
{
SListNode* new = BuySListNode(x);
if (*pplist == NULL)
{
*pplist = new;
}
else {
SListNode* tail = *pplist;
while (tail->next != NULL)
{
tail = tail->next;
}tail->next = new;
}
}
与头插不同,多了个找尾的工作(这里就比顺序表麻烦了点╮(╯﹏╰)╭)
(4)自定义插入
思路是新数据接上上一个的next再在自己的next内存放下一个数据的地址(因为只存放了下一个数据的地址,所以在自定义位置后插入会比在前插入容易)
思路如图
void SListInsertAfter(SListNode* plist, SListNode* pos, SLTDateType x) {
assert(pos);
SListNode* Next, *new;
Next = pos->next;
new = BuySListNode(x);
new->next = Next;
pos->next = new;
}
同理可以通过修改pos来简化头插(尾插还得提前找尾)
2、删减内容
(1)头删
void SListPopFront(SListNode** pplist) {
assert(pplist);
SListNode* first = *pplist;
*pplist = first->next;
free(first);
first = NULL;
}
完事后记得把原来头的内存释放掉就好
(2)尾删
void SListPopBack(SListNode** pplist) {
assert(pplist);
if ((*pplist)->next== NULL)
{
free(*pplist);
*pplist = NULL;
}
else {
SListNode* tail = *pplist;
while (tail->next->next!=NULL)
{
tail = tail->next;
}
free(tail->next);
tail->next = NULL;
}
}
除了找尾以外和头删大同小异(笑)
(3)自定义位置删除
将前后链接起来自己释放就好
void SListEraseAfter(SListNode* pos) {
assert(pos);
SListNode* Next;
assert(pos->next);
Next = pos->next->next;
free(pos->next);
pos->next = Next;
}
3、寻找内容
SListNode* SListFind(SListNode* plist, SLTDateType x) {
assert(plist);
SListNode* c = plist;
while (c)
{
if (c->data == x)
{
return c;
}
else {
c= c->next;
}
}return NULL;
}
找得到返回地址找不到只能返回个空了罢
4、打印单链表
void SListPrint(SListNode* plist)
{
SListNode* c = plist;
while (c )
{
printf("%d->",c->data);
c=c->next;
}printf("NULL\n");
}
不能用数组方式了呢只好一步步看有没有打完
5、删除单链表
走一步释放一步;( ̄︶ ̄)↗( ̄︶ ̄)↗( ̄︶ ̄)↗
void SListDestroy(SListNode* plist)
{
assert(plist);
SListNode* a = plist;
while (plist->next!=NULL)
{
plist = plist->next;
free(a);
a = plist;
}free(a);
}
三、后话
对指针要求比顺序表高了那么一点点(时不时就能看见自己的指针有一种野性的美感<( ̄ ﹌  ̄)> 让人欲罢不能)