数据结构——单链表

目录

一、打印链表

二、建立新节点函数

三、尾插

四、头插

五、尾删

六、头删

七、指定数删除

八、在pos位置之前插入

九、在pos之后插入

十、删除pos 位置

十一、删除pos位置后面的值

十二、删除所有节点(清空)

一、打印链表

void SListPrint(SListNode* phead)//打印链表直到为空

{

SListNode* cur = phead;//使当前指针从头指针开始,遍历指针

while (cur != NULL)

{

printf("%d->", cur->data);

cur = cur->next;

}

printf("NULL\n");//最后别忘了空指针

}

二、建立新节点函数

向内存申请空间,建立新节点,新节点为空,扩容失败退出,否则返回一个新指针

因为用的很多单独写一个函数

SListNode* BuySListNode(SLTDataType x)

{

SListNode* newnode = (SListNode*)malloc(sizeof(SListNode));

if (newnode == NULL)

{

printf("malloc fail\n");

exit(-1);

}

else

{

newnode->data = x;

newnode->next = NULL;

}



return newnode;

}

三、尾插

void SListPushBack(SListNode** pphead, SLTDataType x)

{

assert(pphead);//断言pphead是否有效



SListNode* newnode = BuySListNode(x);//调取函数申请空间存储新节点

if (*pphead == NULL)//这一种要单拎出来,因为找节点找的是当前节点的上一个节点,而如果它本来就是头结点就没有上一个节点,需特殊讨论

{

*pphead = newnode;

}

else

{

// 找尾

SListNode* tail = *pphead;//使尾节点为头结点,然后遍历尾节点直到为空,此时使尾节点的下一个节点为要插入的新节点

while (tail->next != NULL)

{

tail = tail->next;

}



tail->next = newnode;



}

}

四、头插

void SListPushFront(SListNode** pphead, SLTDataType x)

{

assert(pphead);//断言pphead是否有效



SListNode* newnode = BuySListNode(x);//调取函数申请空间存储新节点

newnode->next = *pphead;//使新节点的下一个为头结点

*pphead = newnode;//此时的头结点就为新结点了,头插成功,一定时刻记着头结点何为节点,函数完成后头结 
                  //点一定是第一个,尾节点是最后一个

}

五、尾删

1、链表空

 2、链表只有一个节点

 3、链表有多个节点

void SListPopBack(SListNode** pphead)

{

assert(pphead); //断言pphead是否有效

// 也可以暴力检查为空的情况

//assert(*pphead != NULL);

if (*pphead == NULL)  // 温柔检查,链表是否为空

{

return;

}

else if ((*pphead)->next == NULL)//只有一个节点为头结点,直接释放头结点,然后头结点置空

{

free(*pphead);

*pphead = NULL;

}

else          //多个节点,使尾结点指向头结点遍历,

{

SListNode* tail = *pphead;

while (tail->next->next != NULL)//找到尾节点的前一个位置

{

tail = tail->next;//然后使尾节点指向尾节点的下一个地址,连接好链表

}


free(tail->next);//释放为节点

tail->next = NULL;//使尾节点的下一个节点置空

}

}

六、头删

 1、链表为空

 2、链表非空

void SListPopFront(SListNode** pphead)

{

assert(pphead);//断言pphead是否有效

if (*pphead == NULL)

{

return;

}

else//存储好头结点的下一个节点的地址,然后释放头结点,最后使得头结点为刚才储存的节点

{

SListNode* next

free(*pphead);

*pphead = next;

}

}

七、指定数删除

建立一个当前节点,遍历节点查找数,如果找到了返回节点,并使当前节点的下一个节点为当前节点,相当于删除了该节点,没找到返回空指针

SListNode* SListFind(SListNode* phead, SLTDataType x)

{

SListNode* cur = phead;

while (cur != NULL)

{

if (cur->data == x)

{

return cur;

}

cur = cur->next;

}

return NULL;

}

八、在pos位置之前插入

 1、pos是第一个节点

 2、pos不是第一个节点

void SListInsert(SListNode** pphead, SListNode* pos, SLTDataType x)

{

assert(pphead);//断言pphead是否有效

assert(pos);//断言pos是否有效

if (pos == *pphead)//pos是头结点

{

SListPushFront(pphead, x);//调用函数头插

}

else                //建立pos的前一个节点为prev,遍历节点,直到prev的后一个节点等于pos时,调用 
                    //函数申请内存,使prev指向新节点,新节点的下一个节点为pos,连接了链表

{

SListNode* prev = *pphead;

while (prev->next != pos)

{

prev = prev->next;

}
SListNode* newnode = BuySListNode(x);//调用函数申请内存

prev->next = newnode;

newnode->next = pos;

}

}

九、在pos之后插入

void SListInsertAfter(SListNode* pos, SLTDataType x)

{

assert(pos);//断言pphead是否有效



SListNode* newnode = BuySListNode(x); //调用函数申请内存为新节点

newnode->next = pos->next;

pos->next = newnode;

}

十、删除pos 位置

void SListErase(SListNode** pphead, SListNode* pos)

{

assert(pphead);//断言pphead是否有效

assert(pos);//断言pos是否有效



if (*pphead == pos)//只有一个节点,为头结点,调用头删函数

{

SListPopFront(pphead);

}

else//多个节点,建立pos的前一个节点为prev,遍历节点,直到prev的后一个节点等于pos时,,使prev指向prev的后一个节点,然后使其指向pos的下一个,跳过pos

{

SListNode* prev = *pphead;

while (prev->next != pos)

{

prev = prev->next;

}
prev->next = pos->next;

free(pos);//释放节点

pos = NULL;//最后必须置空,避免野指针的出现

}

}

十一、删除pos位置后面的值

void SListEraseAfter(SListNode* pos)

{

assert(pos);//断言pos是否有效

SListNode* next = pos->next;//建立next节点,使其对于pos下一个节点

if (next)//如果pos下一个节点不为空,pos->next = next->next跳过了next(删除pos位置后面的值)

{

pos->next = next->next;

free(next);//释放节点

next = NULL;//最后必须置空,避免野指针的出现

}

}

十二、删除所有节点(清空)

void SListDestroy(SListNode** pphead)

{

assert(pphead);//断言pphead是否有效

SListNode* cur = *pphead;//建立当前指,使其为头指针

while (cur)

{

SListNode* next = cur->next;//遍历节点

free(cur);//释放cur

cur = next;

}

*pphead = NULL;//最后必须置空,避免野指针的出现

}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

jiao₍˄·͈༝·͈˄*₎◞ ̑̑

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值