首页 > 其他分享 >【链表】单链表-增-删-查(C语言)

【链表】单链表-增-删-查(C语言)

时间:2022-11-17 21:36:29浏览次数:51  
标签:pphead 结点 单链 SLTNode pos next 链表 newnode C语言



我的小站——半生瓜のblog


【链表】单链表-增-删-查(C语言)_链表

单链表

  • ​​结构体定义​​
  • ​​打印​​
  • ​​创建结点​​
  • ​​尾插​​
  • ​​头插​​
  • ​​尾删​​
  • ​​头删​​
  • ​​查找​​
  • ​​在指定位置前插入某个数据​​
  • ​​删除指定位置数据​​
  • ​​全部代码​​

结构体定义

typedef int SLTDataType;
typedef struct SListNode
{
SLTDataType data;
struct SListNode* next;
}SLTNode;

打印

void SLTPrint(SLTNode* phead)
{
SLTNode* cur = phead;
while (cur !=NULL)
{
printf("%d ", cur->data);
cur = cur->next;
}
printf("\n");
}

创建结点

SLTNode* SLTCreat(SLTDataType x)
{
SLTNode* newnode = (SLTNode*)malloc(sizeof(SLTNode));
newnode->data = x;
newnode->next = NULL;
return newnode;
}

尾插

void SLTPushBack(SLTNode** pphead, SLTDataType x)
{
//创建新结点
SLTNode* newnode = SLTCreat(x);
//如果是空链表
if (*pphead == NULL)
{
*pphead = newnode;
}
else
{
//找到尾结点
SLTNode* tail = *pphead;
while (tail->next != NULL)
{
tail = tail->next;
}
tail->next = newnode;
}
}

头插

void SLTPushFront(SLTNode** pphead, SLTDataType x)
{
//创建新结点
SLTNode* newnode = SLTCreat(x);
newnode->next = *pphead;
*pphead = newnode;
}

尾删

void SLTPopBack(SLTNode** pphead)
{
//空链表
if (*pphead == NULL)
{
return ;
}
//链表中只有一个结点
else if ((*pphead)->next == NULL)
{
free(*pphead);
*pphead = NULL;
}
//一个以上结点
else
{
//找到尾结点
SLTNode* tail = *pphead;
//找到尾结点的前一个结点
SLTNode* tailPrev = NULL;
while (tail->next != NULL)
{
tailPrev = tail;
tail = tail->next;
}
free(tail);
tailPrev->next = NULL;

}

}

头删

void SLTPopFront(SLTNode** pphead)
{
//如果直接free pphead就会找不到后面的结点了
//先保存下一个
SLTNode* ppheadNext = (*pphead)->next;//这里要加一个括号,因为*和->都是解引用,*是对任意的指针都可以解引用,取它指向的这个位置的数据,什么类型的指针就取几个字节,->是结构体的,这时候他们两个的优先级是一样的。
free(*pphead);
//这时候第一个数据就是之前第二个数据了
*pphead = ppheadNext;
}

查找

下面的删除和插入都要在先在链表中找到为前提。

SLTNode* SLTFind(SLTNode* phead,SLTDataType x)
{
SLTNode* pos = phead;
while (pos != NULL)
{
if (pos->data == x)
{
return pos;
}
pos = pos->next;
}
return NULL;
}

在指定位置前插入某个数据

void SLTInsert(SLTNode** pphead,SLTNode* pos, SLTDataType x)
{
//如果在第一个结点前插入数据
//那就是头插,直接调用头插的函数
if (pos == *pphead)
{
SLTPushFront(pphead,x);
}
else
{
//创建一个新结点来存放新的数据
SLTNode* newnode = SLTCreat(x);
//要在pos前面插入newnode,就得先找到pos前面的内个结点
SLTNode* posPrev = *pphead;
while (posPrev->next != pos)
{
posPrev = posPrev->next;
}
//链接起来
posPrev->next = newnode;
newnode->next = pos;
}
}

删除指定位置数据

void SLTErase(SLTNode** pphead, SLTNode*pos)
{
//当删除第一个结点的时候,无法找到他的前一个结点
if (pos == *pphead)
{
SLTPopFront(pphead);
}
else
{
//单链表每次老是要寻找前一个结点
SLTNode* posPrev = *pphead;
while (posPrev->next != pos)
{
posPrev = posPrev->next;
}
posPrev->next = pos->next;
free(pos);
}
}

全部代码

#include<stdio.h>
#include<stdlib.h>
//定义结构
typedef int SLTDataType;
typedef struct SListNode
{
SLTDataType data;
struct SListNode* next;
}SLTNode;
//改变头结点的传2级指针,不改变的传1级指针
//打印
void SLTPrint(SLTNode* phead)
{
SLTNode* cur = phead;
while (cur !=NULL)
{
printf("%d ", cur->data);
cur = cur->next;
}
printf("\n");
}
//创建结点
SLTNode* SLTCreat(SLTDataType x)
{
SLTNode* newnode = (SLTNode*)malloc(sizeof(SLTNode));
newnode->data = x;
newnode->next = NULL;
return newnode;
}
//尾插
void SLTPushBack(SLTNode** pphead, SLTDataType x)
{
//创建新结点
SLTNode* newnode = SLTCreat(x);
//如果是空链表
if (*pphead == NULL)
{
*pphead = newnode;
}
else
{
//找到尾结点
SLTNode* tail = *pphead;
while (tail->next != NULL)
{
tail = tail->next;
}
tail->next = newnode;
}
}
//头插
void SLTPushFront(SLTNode** pphead, SLTDataType x)
{
//创建新结点
SLTNode* newnode = SLTCreat(x);
newnode->next = *pphead;
*pphead = newnode;
}
//尾删
void SLTPopBack(SLTNode** pphead)
{
//空链表
if (*pphead == NULL)
{
return ;
}
//链表中只有一个结点
else if ((*pphead)->next == NULL)
{
free(*pphead);
*pphead = NULL;
}
//一个以上结点
else
{
//找到尾结点
SLTNode* tail = *pphead;
//找到尾结点的前一个结点
SLTNode* tailPrev = NULL;
while (tail->next != NULL)
{
tailPrev = tail;
tail = tail->next;
}
free(tail);
tailPrev->next = NULL;

}

}
//头删
void SLTPopFront(SLTNode** pphead)
{
//如果直接free pphead就会找不到后面的结点了
//先保存下一个
SLTNode* ppheadNext = (*pphead)->next;//这里要加一个括号,因为*和->都是解引用,*是对任意的指针都可以解引用,取它指向的这个位置的数据,什么类型的指针就取几个字节,->是结构体的,这时候他们两个的优先级是一样的。
free(*pphead);
//这时候第一个数据就是之前第二个数据了
*pphead = ppheadNext;
}
//查找
SLTNode* SLTFind(SLTNode* phead,SLTDataType x)
{
SLTNode* pos = phead;
while (pos != NULL)
{
if (pos->data == x)
{
return pos;
}
pos = pos->next;
}
return NULL;
}
//在pos前插入某个数据
void SLTInsert(SLTNode** pphead,SLTNode* pos, SLTDataType x)
{
//如果在第一个结点前插入数据
//那就是头插,直接调用头插的函数
if (pos == *pphead)
{
SLTPushFront(pphead,x);
}
else
{
//创建一个新结点来存放新的数据
SLTNode* newnode = SLTCreat(x);
//要在pos前面插入newnode,就得先找到pos前面的内个结点
SLTNode* posPrev = *pphead;
while (posPrev->next != pos)
{
posPrev = posPrev->next;
}
//链接起来
posPrev->next = newnode;
newnode->next = pos;
}
}
//删除pos位置的数据
void SLTErase(SLTNode** pphead, SLTNode*pos)
{
//当删除第一个结点的时候,无法找到他的前一个结点
if (pos == *pphead)
{
SLTPopFront(pphead);
}
else
{
//单链表每次老是要寻找前一个结点
SLTNode* posPrev = *pphead;
while (posPrev->next != pos)
{
posPrev = posPrev->next;
}
posPrev->next = pos->next;
free(pos);
}
}
//测试
void Test1()
{
SLTNode* plist = NULL;
SLTPushBack(&plist, 0);
SLTPushBack(&plist, 2);
SLTPushBack(&plist, 3);
SLTPushBack(&plist, 4);
SLTPrint(plist);

SLTNode* pos = SLTFind(plist, 0);
if (pos != NULL)
{
//说明找到了
SLTErase(&plist, pos);
}
SLTPrint(plist);


}
int main(void)
{
Test1();
return 0;
}


标签:pphead,结点,单链,SLTNode,pos,next,链表,newnode,C语言
From: https://blog.51cto.com/u_15333750/5866180

相关文章

  • 【线性表】之顺序表(C语言)
    【线性表】之顺序表​​线性表​​​​顺序表​​​​结构定义​​​​初始化​​​​销毁​​​​打印​​​​扩展空间​​​​尾插​​​​头插​​​​尾删​​​​头删......
  • LeetCode刷题(4)【移除元素&合并两个有序数组】(C语言)(含图解)
    移除元素典型双指针玩法。27.移除元素-力扣(LeetCode)(leetcode-cn.com)我们都会想到这样的解法:从前面依次往后推,是val就将该数据后面的元素依次覆盖上来,但是这样的时间复......
  • LeetCode刷题(5)【链表】【环形链表II】(C语言)
    环形链表I​​LeetCode刷题(3)【链表】【环形链表】&扩展_半生瓜のblog-CSDN博客​​环形链表II142.环形链表II-力扣(LeetCode)(leetcode-cn.com)这个题写起来不难,但是证......
  • 【线性表】之栈(C语言)
    栈​​回顾​​​​栈​​​​结构定义​​​​初始化​​​​销毁​​​​入栈​​​​出栈​​​​返回栈顶元素​​​​返回栈中元素个数​​​​判断栈是否为空​​​​......
  • 【线性表】之队列(C语言)
    队列​​队列的概念​​​​结构定义​​​​初始化​​​​销毁​​​​队尾入​​​​队头出​​​​队头出​​​​队头数据​​​​队尾数据​​​​是否为空​​​​返......
  • LeetCode刷题(7)【栈&队列】用队列实现栈(C语言)
    用队列实现栈225.用队列实现栈-力扣(LeetCode)(leetcode-cn.com)目的:用队列实现栈,从先进先出——>先进后出,1234这四个数据依次从队列1的队尾进入,要让4先出,一个队列是无法......
  • LeetCode刷题(2)【链表】【合链表&链表的中间结点】(C语言)
    我的小站——半生瓜のblog快慢指针问题:思路:定义一个快指针和一个慢指针,快指针走到结束的时候,慢指针刚好走到一半。链表的中间结点。876.链表的中间结点-力扣(LeetCode)(le......
  • LeetCode刷题(3)【链表】【环形链表】&扩展(C语言)
    我的小站——半生瓜のblog环形链表141.环形链表-力扣(LeetCode)(leetcode-cn.com)什么是链表带环:链表的最后一个元素不指向空而指向前面的某个结点。思路:快慢指针,慢指针走......
  • C语言二级错题积累(4)
    在栈中,栈项指针的动态变化决定栈中元素的个数。详细设计的人物是为软件结构体中的每一个模块确定实现算法和局部数据结构,用某种选定的表达工具表示算法和数据结构的细节。扇......
  • C语言二级错题积累(5)
    常用的连续存储管理技术有固定分区存储管理和可变分区存储管理。程序流程图中带有箭头的线段表示的是控制流。若二叉树没有叶子结点,则为空二叉树。带链栈的栈底指针是随栈的......