【单链表】的增删查改

这篇具有很好参考价值的文章主要介绍了【单链表】的增删查改。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

🖊作者 : Djx_hmbb
📘专栏 : 数据结构
😆今日分享 : “Onc in a blu moon” : “罕见的,千载难逢的” (出现在19世纪,指的是"在一个月内出现的第二次圆月”,这种现象每隔32个月发生一次。)
【单链表】的增删查改文章来源地址https://www.toymoban.com/news/detail-426561.html

✔单链表的功能实现:

🔎申请一个结点空间 :

//为单链表申请一个结点空间
SLT* SLTBuy(SLTdataType x)
{
	SLT* newNode = (SLT*)malloc(sizeof(SLT));
	if (newNode == NULL) 
	{
		perror("malloc fail:");
		exit(-1);
	}
	else
	{
		newNode->data = x;
		newNode->next = NULL;
	}
	return newNode;
}

🔎构建n个链表 :

//构建n个链表
SLT* SLTCreate(SLTdataType x)
{
	SLT* phead = NULL, * ptail = NULL;
	for (int i = 0; i < x; i++)
	{
		SLT* newNdoe = SLTBuy(i);
		if (phead == NULL)
		{
			phead = ptail = newNdoe;
		}
		else 
		{
			ptail->next = newNdoe;
			ptail = newNdoe;
		}
	}
	return phead;
}

🔎打印链表 :

//打印链表
void SLTPrint(SLT* phead)
{
	SLT* cur = phead;
	while (cur != NULL)
	{
		printf("%d ",cur->data);
		cur = cur->next;
	}
	 puts("NULL\n");
}

🔎尾插 :

//尾插!!!!!!!!!!!!!!!!!!要用取地址!!!!!!!!!!!
void SLTPushBack(SLT** pphead, SLTdataType x) 
{
	SLT* newNode=SLTBuy(x);
	
	if (*pphead == NULL)
	{
		*pphead = newNode;
	}
	else
	{
		SLT* ptail = *pphead;
		//找尾结点
		while (ptail->next)
		{
		//移动指针
			ptail = ptail->next;
		}
		//将新建的结点插入尾结点
		ptail->next = newNode;
	}
	
}

🔎尾删 :

//尾删
void SLTPopBack(SLT** pphead)
{
	assert(*pphead);//检查链表头结点是否为空

	//法一:
	SLT* ptail = (*pphead)->next;
	SLT* cur = *pphead;
	//判断头结点是否为空
	 if(*pphead != NULL)
	 {
	//判断第二个节点是否为空(ptail)
		 if ((*pphead)->next != NULL)
		 { //找尾
			 //SLT* ptail = (*pphead)->next;
			 while (ptail->next)
			{
				cur = ptail;
				ptail = ptail->next;
			}
	//找到尾后,释放空间,并将前面的一个结点置为空
			free(ptail);
			cur->next = NULL;
		 }
		 else
		 {
			 free(*pphead);
			 *pphead = NULL;
		 }
	 }
	 else
	 {
		 free(*pphead);
		 *pphead = NULL;
	 }
	
	

	法二:
	//SLT* ptail = *pphead;
	找尾
	//if (ptail->next)
	//{
	//	while (ptail->next->next)
	//{
	//	ptail = ptail->next;
	//}
	找到尾后,释放空间,并将前面的一个结点值为空
	//free(ptail->next);
	//ptail->next = NULL;
	//}
	//else
	//{
	//	free(*pphead);
	//	*pphead = NULL;
	//}
	
}

🔎头插 :

//头插
void SLTPushFront(SLT** pphead, SLTdataType x)
{
	SLT* newNode = SLTBuy(x);
	if (*pphead==NULL)
	{
		*pphead = newNode;
	}
	else
	{
		SLT* ptail = (*pphead);
		//SLT* cur = (*pphead)->next;
		*pphead = newNode;
		newNode->next = ptail;
		ptail = *pphead;
	}
}

🔎头删 :

//头删
void SLTPopFront(SLT** pphead)
{
	if (*pphead == NULL)
	{//释放原空间
		free(*pphead);
		(*pphead) = NULL;
	}
	else
	{//删除
		SLT* ptail = (*pphead)->next;
		if (ptail != NULL)
		{
			(*pphead) = ptail;
		}
		else
		{
			free(*pphead);
			(*pphead) = NULL;
		}
	}
}

🔎查找 :

//查找
SLT* SLTFind(SLT* phead, SLTdataType x)
{
	assert(phead);
	SLT* cur = phead;
	while (cur != NULL)
	{
		//找x
		while (cur->data != x)
		{
		cur = cur->next;
		}
		//找到后,返回地址
		return cur;
	}
	return NULL;
}

🔎在pos位置后插入x :

//在pos位置后插入x
void SLTInsertAfter(SLT* pos, SLTdataType x)
{
	assert(pos);//判断pos位置是否存在
	SLT* newNode = SLTBuy(x);
	newNode->next = pos->next;
	pos->next = newNode;
}

🔎在pos位置前插入x :

//在pos位置前插入x
void SLTInsertFront(SLT** pphead, SLT* pos, SLTdataType x)
{
	assert(pos);
	if (*pphead == pos)
	{
		SLTPushFront(pphead,x);
	}
	else
	{
		SLT* prev = *pphead;
		//找到pos的前一个结点
		while (prev->next != pos)
		{
			prev = prev->next;
		}
		//找到后,添加节点
		SLT* newNode = SLTBuy(x);
		prev->next = newNode;
		newNode->next = pos;
	}
}

🔎删除pos位置后一个指针 :

//删除pos位置后一个指针
void SLTDeleteAfter(SLT* pos)
{
	assert(pos);
	if (pos->next == NULL)
	{
		return ;
	}
	else
	{
		pos->next = pos->next->next;
	}
}

🔎删除pos位置的指针 :

//删除pos位置的指针
void SLTDPosDelete(SLT** pphead, SLT* pos)
{
	//assert(*pphead);//不用断言,如果plist为空,则pos一定为空;可是plist不为空,但是pos可能为空!!!
	assert(pos);
	if (pos == *pphead)
	{
		SLTPopFront(pphead);
	}
	else
	{
		SLT* prev = *pphead;
		//找到pos前一个节点
		while (prev->next != pos)
		{
			prev = prev->next;
		}
		//删除pos结点
		prev->next = pos->next;
		free(pos);
		//pos = NULL;//不用置空,无意义:置空的是形参
	}
}

🔎释放空间 :

//释放空间
void SLTDestory(SLT** pphead)
{
	//结点是一个一个申请的,所以释放的时候也需要一个一个释放!!!
	// 错误示范:
	//free(*pphead);
	//(*pphead)->next = NULL;

	//正确:
	SLT* cur = *pphead;
	while (cur != NULL)
	{
		SLT* next = cur->next;
		free(cur);
		cur = next;
	}
	*pphead = NULL;//头指针此时为野指针,需要置空
}

✔头文件(详情):

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<malloc.h>
#include<assert.h>

#define SLTdataType int

//定义结构体
typedef struct SLTnode
{
	SLTdataType data;
	struct  SLTnode* next;
}SLT; 

//为结点申请一个空间
SLT* SLTBuy(SLTdataType x);

//构建n个链表
SLT* SLTCreate(SLTdataType x);

//打印链表
void SLTPrint(SLT* phead);

//尾插
void SLTPushBack(SLT** pphead,SLTdataType x);

//尾删
void SLTPopBack(SLT** pphead);

//头插
void SLTPushFront(SLT** pphead, SLTdataType x);

//头删
void SLTPopFront(SLT** pphead);

//查找
SLT* SLTFind(SLT* phead, SLTdataType x);

//在pos位置后插入x
void SLTInsertAfter(SLT* pos, SLTdataType x);

//在pos位置前插入x
void SLTInsertFront(SLT** pphead,SLT* pos, SLTdataType x);

//删除pos位置后一个指针
void SLTDeleteAfter(SLT* pos);

//删除pos位置的指针
void SLTDPosDelete(SLT** pphead, SLT* pos);

//释放空间
void SLTDestory(SLT** pphead);

✔测试文件(详情):

#define _CRT_SECURE_NO_WARNINGS
#include"SLTNode.h"



test01()
{
	SLT* b1 = SLTBuy(1);
	SLT* b2 = SLTBuy(2);
	SLT* b3 = SLTBuy(3);
	b1->next = b2;
	b2->next = b3;
	SLTPrint(b1);
}

test02()
{
	SLT* plist= SLTCreate(3);
	SLTPrint(plist);
}

test03()
{
	SLT* plist=SLTCreate(3);//0 1 2
	/*int x = 0;
	printf("请输入尾插的数字:");
	scanf("%d",&x);
	SLTPushBack(&plist,x);
	SLTPrint(plist);*/
	//SLTPopBack(&plist);//0 1
	//SLTPrint(plist);
	//SLTPopBack(&plist);//0
	//SLTPrint(plist);
	//SLTPopBack(&plist);//NULL
	//SLTPrint(plist);
}
test04()
{
	SLT* plist = SLTCreate(3);//0 1 2
	//int x = 0;
	//printf("请输入头插的值:");
	//scanf("%d",&x);
	SLTPushFront(&plist,3);
	SLTPrint(plist);

	SLTPopFront(&plist);
	SLTPrint(plist);//0 1 2
	SLTPopFront(&plist);
	SLTPrint(plist);//1 2
	SLTPopFront(&plist);
	SLTPrint(plist);// 2
	SLTPopFront(&plist);
	SLTPrint(plist);//NULL
}
test05()
{
	SLT* plist = NULL;
	SLTPushFront(&plist, 3);
	SLTPushFront(&plist, 2);
	SLTPushFront(&plist, 1);
	SLTPushFront(&plist, 0);
	SLTPrint(plist);//0 1 2 3 NULL

	SLT* pos = SLTFind(plist,3);
	printf("%p\n",pos);//000002866BDFE0E0

	SLTInsertAfter(pos,12);
	SLTPrint(plist);//0 1 2 3 12 NULL
	SLTInsertFront(&plist,pos,11);
	SLTPrint(plist);//0 1 2 11 3 12 NULL

	SLTDeleteAfter(pos);
	SLTPrint(plist);//0 1 2 11 3 NULL

	pos = SLTFind(plist,0);
	SLTDPosDelete(&plist,pos);
	SLTPrint(plist);//0 1 2 11 NULL

}
main()
{
	test05();
	system("pause");
	return 0;
}

感谢家人的阅读,若有不准确的地方 欢迎在评论区指正!

家人们,点个再走呗~

到了这里,关于【单链表】的增删查改的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Mybatis之增删查改

    目录 一、引言 二、Mybatis——查询 示例:查询用户 三、Mybatis——添加 示例:添加用户 四、Mybatis——删除 示例:删除用户 五、Mybatis——修改 示例:修改用户 接着上次的mybatis,我们在了解完mybatis之后,肯定要知道怎么使用,本文就来详细讲解Mybatis的增删改查事务,还不

    2024年02月03日
    浏览(55)
  • Mybatis基础---------增删查改

    目录结构 增删改 1、新建工具类用来获取会话对象 2、加入junit依赖 3、通过映射传递属性 之前的sql语句全部写在了映射文件中,然而在实际应用时是通过映射传递属性的,也就是java对象对应sql语句中的占位符属性,属性名一般和java对象中的属性名相同,我们只需要用#{}作为

    2024年01月17日
    浏览(47)
  • 详解MySQL增删查改

    众所周知,MySQL是非常重要的数据库语言,下面我们来回顾一下mysql的增删查改吧 MySQL创建数据库: MySQL删除数据库: MySQL删除数据库 MySQL创建数据库 MySQL增加字段 MySQL修改字段类型 MySQL修改字段名称 MySQL删除字段类型 MySQL增加字段且非空依赖 MySQL修改字段依赖 MySQL添加主键依

    2024年02月20日
    浏览(50)
  • MySQL——表的增删查改

    目录 一.Create(创建) 1.单行数据 + 全列插入 2.多行数据 + 指定列插入 3.插入否则更新 4. 替换 二.Retrieve(读取) 1. select 列 查询 2.where 条件 3.结果排序 4.筛选分页结果 三.Update (修改) 四.Delete(删除) 1.删除数据 2.删除整张表数据 3.截断表 4.去重表数据 五.聚合函数 六.g

    2024年02月04日
    浏览(67)
  • 【MySql】表的增删查改

    说明: field 表示列名 datatype 表示列的类型 character set 字符集,如果没有指定字符集,则以所在数据库的字符集为准 collate 校验规则,如果没有指定校验规则,则以所在数据库的校验规则为准 现在创建一张表user1: 创建表user2: 存储引擎不同,此时我们查看user1和user2:建表的时候

    2024年02月08日
    浏览(53)
  • Spring boot增删查改

    前言 一、项目结构 二、创建项目、运行环境 三、配置数据库 四、Model 五、Repository 六、Service 1、接口类 2、实现类 七、Controller 八、Web页面 1、index 2、new_food 3、update_food 九、Web页面展示  十、总结 Spring 是一个开源框架,可以轻松创建独立的、生产级的基于 Spring 的应用程序

    2024年02月07日
    浏览(31)
  • MySQL基础——增删查改(基础)

    目录 1.前言 2.铺垫 3.正片   经过前面一段时间数据结构基础的学习,现在我们终于来到了MySQL的学习。我们先简单介绍一下什么是数据库。 为了解决 海量文件的存储与管理 问题,专家们设计出更加利于管理数据的软件——数据库,它能更有效的管理数据。数据 库可以提供远

    2024年02月06日
    浏览(46)
  • 【MySQL】增删查改基础

    需要云服务器等云产品来学习Linux的同学可以移步/--腾讯云--/--阿里云--/--华为云--/官网,轻量型云服务器低至112元/年,新用户首次下单享超低折扣。    目录 一、Create(创建) 1、insert(插入) 1.1单行数据插入 1.2多行数据插入 1.3插入或者替换更新 2、replace(替换) 二、Retrieve(读取

    2024年02月09日
    浏览(50)
  • 【MySQL】表的增删查改(进阶)

    目录 1.数据库约束 1.1NOT NULL:非空约束 1.2UNIQUE:唯一值约束 1.3DEFAULT:默认值约束 1.4PRIMARY KEY:主键约束 1.5FOREIGN KEY:外键约束 1.6CHECK约束 2.表的设计 2.1一对一 2.2一对多 2.3多对多 3.新增 4.查询 4.1聚合查询 4.1.1聚合查询 4.1.2GROUP BY 4.2联合查询 4.2.1内连接  4.2.2外连接 4.2.3自连

    2024年02月11日
    浏览(43)
  • Linux下文件的增删查改

    1.什么是文件 文件是计算机文件属于文件的一种,与普通文件载体不同,计算机文件是以计算机硬盘为载体存储在计算机上的信息集合。文件=文件内容+文件属性。 2.文件的创建 文件的创建分为两种指令: touch 和 mkdir touch是用来创建普通文件的 : 普通文件分为文本文件、各

    2024年02月04日
    浏览(5)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包