前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【链表】单链表-增-删-查(C语言)

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

作者头像
半生瓜的blog
发布2023-05-12 21:19:38
6900
发布2023-05-12 21:19:38
举报
文章被收录于专栏:半生瓜のblog半生瓜のblog


在这里插入图片描述
在这里插入图片描述

结构体定义

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;
}
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2021-06-02,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 结构体定义
  • 打印
  • 创建结点
  • 尾插
  • 头插
  • 尾删
  • 头删
  • 查找
  • 在指定位置前插入某个数据
  • 删除指定位置数据
  • 全部代码
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档