数据结构—单链表

news2025/1/24 8:31:32

目录

1.前言

2.了解单链表

3.单链表代码实现

      3.1 单链表结构体实现

      3.2 创建节点

      3.3  打印单链表

      3.4 尾插 

      3.5  头插 

      3. 6 头删

      3.7  尾删

      3.8  查找

      3.9  插入

           3.9.1 在pos位置之前插入 

           3.9.2  在pos位置之后插入(主要使用这种功能)---不需要找pos前一个

      3.10 删除

             3.10.1 删除pos位置的值

             3.10.2  删除pos后一个(主要使用这种功能)---不需要找pos前一个

      3.11 单链表总结


1.前言

          学习了顺序表发现有以下缺点:


        1.1 空间不够,需要扩容(扩容有一定的空间浪费)。

        1.2 头插、头删(需要移动数据)时间复杂度是O(N),效率低。

         所以我们学习单链表来按需申请释放空间,不需要移动数据,提高效率。


2.了解单链表

  概念:单链表是一种链式存取的数据结构,用一组地址任意的存储单元存放线性表中的数据元素。

  特点:每个结点除了存放数据元素外,还要存储指向下一个节点的指针

  优点:不要求大片连续空间,改变容量方便。。

  缺点:不可随机存取,要耗费一定空间存放指针。

  单链表逻辑及重要性:


3.单链表代码实现

      3.1 单链表结构体实现

typedef int SLTDataType; 
typedef struct SListNode
{
	SLTDataType data;//存放数据
	struct SListNode* next;//指向下一个结构体的指针
}SLTNode;

       3.2 创建节点

void TestSList1()
{
	//struct SListNode* 
	SLTNode* n1 = (SLTNode*)malloc(sizeof(SLTNode));
	assert(n1);
	SLTNode* n2 = (SLTNode*)malloc(sizeof(SLTNode));
	assert(n2);
	SLTNode* n3 = (SLTNode*)malloc(sizeof(SLTNode));
	assert(n3);
	SLTNode* n4 = (SLTNode*)malloc(sizeof(SLTNode));
	assert(n4);

	n1->data = 1;
	n2->data = 2;
	n3->data = 3;
	n4->data = 4;

	n1->next = n2;
	n2->next = n3;
	n3->next = n4;
	n4->next = NULL;
}

      3.3  打印单链表

cur = cur->next理解:

第一次进来cur指向的是链表的头,cur=cur—>next说明把下一个节点的地址赋给cur,现在的cur指向的是第二个结构体,是第二个结构体的地址.......

循环下去就可以打印出节点里的data数据,直到cur=NULL。

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

       3.4 尾插 

 注意点:

当链表为空的时候,newnode给phead时,由于phead是一个形参,函数中形参的改变不会改变实参。

这时要改变指针变量(plist)就要传指针变量的地址——就要传二级指针。

void SListPushBack(SLTNode** pphead, SLTDataType x)
{
	SLTNode* newnode = BuySListNode(x);

	if (*pphead == NULL)
	{
		*pphead = newnode;
	}
	else
	{
		// 找尾节点
		SLTNode* tail = *pphead;
		while (tail->next != NULL)
		{
			tail = tail->next;
		}

		tail->next = newnode;
	}
}

         3.5  头插 

单链表头插不需要和尾插一样要特殊处理

void SListPushFront(SLTNode** pphead, SLTDataType x)
{
	SLTNode* newnode = BuySListNode(x);
	newnode->next = *pphead;
	*pphead = newnode;
}

          3. 6 头删

void SListPopFront(SLTNode** pphead)
{
	assert(*pphead != NULL);//暴力检查
	//if (*pphead == NULL)  //温柔检查
	//	return;

	SLTNode* next = (*pphead)->next;
	free(*pphead);
	*pphead = next;
}

         3.7  尾删

void SListPopBack(SLTNode** pphead)
{
	assert(*pphead);

	// 1、只有一个节点
	// 2、多个节点
	if ((*pphead)->next == NULL)
	{
		free(*pphead);
		*pphead = NULL;
	}
	else
	{  
        //两种方法   
		/*SLTNode* tailPrev = NULL;
		SLTNode* tail = *pphead;
		while (tail->next != NULL)
		{
			tailPrev = tail;
			tail = tail->next;
		}
		free(tail);
		tailPrev->next = NULL;*/
//
		SLTNode* tail = *pphead;
		while (tail->next->next != NULL)
		{
			tail = tail->next;
		}
		free(tail->next);
		tail->next = NULL;
	}	
}

      3.8  查找

SLTNode* SListFind(SLTNode* phead, SLTDataType x)
{
	SLTNode* cur = phead;
	while (cur)
	{
		if (cur->data == x)
			return cur;

		cur = cur->next;
	}

	return NULL;
}

       3.9  插入

              3.9.1 在pos位置之前插入 

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

{  
  assert(pos);
  assert(ppheart);
  
  //头插
  if (pos= *pphead)
  {
    
      SListPushFront(pphead.x);
  }
  
  else
   {
         SLTNNode* prev= *ppheart;
         while(prev->next !=pos)

           {
                 prev=prev->next;
           }
         
           SLTNode* newnode=BuySListNode(x);
           prev->next=newnode;
           newnode->next=pos;  

   }

           3.9.2  在pos位置之后插入(主要使用这种功能)---不需要找pos前一个

void SListInsertAfter(SLTNode* pos, SLTDataType x)
{
	assert(pos);

	/*SLTNode* newnode = BuySListNode(x);
	newnode->next = pos->next;
	pos->next = newnode;*/

	// 不在乎链接顺序
	SLTNode* newnode = BuySListNode(x);
	SLTNode* next = pos->next;
	// pos newnode next
	pos->next = newnode;
	newnode->next = next;
}

      3.10 删除

             3.10.1 删除pos位置的值

void SListErase(SLTNode** pphead, SLTNode* pos, SLTDataType x)
{
   assert(pos);
  assert(ppheart);
    
   //头删    
   if (pos= *pphead)
   {
    
       SListPopFront(pphead);
   }
   
    else
    { 
       SLTNode* prev= *pphesd;
       while(prev->next !=pos)
        {
            prev=prev->next;
        }
    
      prev->next= pos->next;
       free(pos);
     }

            3.10.2  删除pos后一个(主要使用这种功能)---不需要找pos前一个

void SListEraseAfter(SLTNode* pos)
{
	assert(pos);

	if (pos->next == NULL)
		return;

	SLTNode* del = pos->next;
	//pos->next = pos->next->next;//这样就释放不了节点
	pos->next = del->next;

	free(del);
	del = NULL;
}

          3.11 单链表总结

        由单链表的在pos位置之后插入和删除pos位置之后的值可知,单链表没有完全解决顺序表的缺陷,所以我们后面学习双向的链表来提高效率。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/433842.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

家用洗地机到底好不好用?家用洗地机分享

在当今社会,人们越来越关注卫生和清洁,这也促进了家庭和工作场所对清洁设备的需求。洗地机就是其中之一,它的高效和便捷性为我们提供了清洁和保洁的重要帮助。使用洗地机不仅能够卫生地保持地面清洁,而且可以节省时间和人力成本。…

拼多多的天天618,如何掀开电商营销的“皇帝新衣”?

电商价格战如火如荼,拼多多也在2023年4月正式启动“数码家电消费季”百亿补贴。 首季将在百亿补贴的基础上加码10亿,对手机、平板等各种数码家电,提供全品类补贴,苹果、华为、小米、美的等国内外各大品牌均会参与。拼多多相关负责…

安装虚拟机VMshare

前言:虚拟机必须在开机的状态下,而且互相需ping通,mobax才可以连接成功 一、下载VMsharePro软件 1、双击 安装程序; 2、按照步骤 点击一个个的“下一步” 3、安装完成之后,会要求你 输入许可证,这个可以…

【Redis】Redis十大数据类型—字符串String

介绍 获取命令地址 英文:https://redis.io/commands/ 中文:http://www.redis.cn/commands.html 字符串(string) 字符串是一种最基本的Redis值类型。Redis字符串是二进制安全的,这意味着一个Redis字符串能包含任意类型的数据,例…

STM:基于Siamese编码器的时空混频器用于CT扫描肺结节生长趋势预测

文章目录 Siamese Encoder-based Spatial-Temporal Mixer for Growth Trend Prediction of Lung Nodules on CT Scans摘要方法Spatial-Temporal MixerTwo-Layer H-Loss 实验结果 Siamese Encoder-based Spatial-Temporal Mixer for Growth Trend Prediction of Lung Nodules on…

JavaScript的三座大山

前言:这个题目是抄的,看着很有意思,就拿过用了,毕竟CV是程序员的基本功底嘛,顺带把图也拿过来了 作用域和闭包 这个几乎是天天在用的东西,可能有些人甚至不知道这个概念,但是用到过这种方法去解…

Dubbo消费者调用流程分析

消费者在发起一次调用的时候时序图如下 由于Dubbo调用是基于动态代理的方式,所以请求先进入 InvokerInvocationHandler#invoke()方法,进而调用到MockClusterInvoker#invoke()方法。MockClusterInvoker#invoke()中判断是否需要开启 Mock,如果开启 Mock 调用 doMockInvoke 执行…

WebRTC系列-Qos系列之AEC-可配置参数

文章目录 1. 简介2. 源码中相关参数WebRTC的自适应回声消除(AEC)是一个广泛使用的技术,用于在音频通信中消除扬声器输出产生的回声。在WebRTC中,有三种AEC算法可供选择,分别是 AECM、 AEC和 AEC3。本文将介绍WebRTC AEC 3算法的原理和应用场景。 在上图中可以看出AEC算…

MiniGPT4,开源了。

大家好,我是 Jack。 一个月前,我发布过一篇文章,讲解了 GPT4 的发布会。 ChatGPT 的对话能力,想必大家也早已体验过了,无论是文本生成能力,还是写代码的能力,甚至是上下文的关联对话能力&#…

SpringBoot自定义登录、权限验证

1、首先最基础的User实体类,使用了lombok,所以省略了getter、setter方法 Data public class UserInfo implements Serializable {private Integer id;//用户名private String username;//密码不需要被序列化存入redisprivate transient String password…

vue3类型uniapp调用signalr

目录 背景 安装 renderjs 1选择一个tab页面承载renderjs代码 2编写业务逻辑代码 3编写renderjs代码 背景 后端使用.net6开发,长链接选择了微软的signalr而非原生的websocket 前端uniapp下vue3类型开发的app,需要通过长链接获取后端推送的消息 安…

通过对话了解cookie session与token的用途和区别

1 先来了解cookie与localstorage 1.1 http的无状态 用户: 我想看csdn我有多少粉丝了(http请求) 服务器:你是?请告诉我你的名字和密码,我确认你是谁 用户:发起登录请求 admin 123456 服务器:ok,登录成功 用户&…

分享几个国内免费的ChatGPT镜像网址(亲测有效)

最近由于ChatGPT的爆火也让很多小伙伴想去感受一下ChatGPT的魅力,那么今天就分享几个ChatGPT国内的镜像网址,大家可以直接使用!记得点赞收藏一下呦! 1、AQ Bot,网址:点我 https://su.askaiw.com/aq 缺点&…

搭建CDH流程记录

搭建CDH流程记录 如何搭建本地yum源 1.配置yum源这里使用 阿里源 http://mirrors.aliyun.com/repo/Centos-7.repo wget http://mirrors.aliyun.com/repo/Centos-7.repo2.安装http软件 yum install httpd -y3.配置httpd.conf vi /etc/httpd/conf/httpd.conf在 AddType appli…

酒店行业开启“狂飙”,尚美数智稳步领跑

文|智能相对论 作者|范柔丝 在消费行业迅速复苏的浪潮下,无论从销量还是数量来看,酒旅行业蛰伏三年后,终于开启了业绩狂飙。 从数量来看,企查查数据显示,截至目前,我国现存酒店相关企业233.5万家&#x…

Grafana链接跳转与值传递,把表格变量值从一个dashboard传递给另一个dashboard

文章目录 1. 创建两个空白 Dashboard 用于实验2. dash_1:创建跳转用的表格2. dash_2:配置接收数据的变量 Variables3. 测试跳转4. 通过跳转的变量传递方法总结 这里,我们一步步的来,通过配置一个页面跳转的效果,把一个…

二结(4.18)项目进度

今天学长上了多线程的课程,内容挺广泛的,部分也需要实际运用到项目中来,但我的登录、注册实现还没区分开服务端和客户端(仅在同一项目里实现) --------------------------------------------------------------------…

【分布式系统】分布式系统架构的冰与火

什么是分布式系统 分布式系统(distributed system)是建立在网络之上的软件系统。 以上是摘自百度百科的解释,不可否则,分布式系统的基础是网络、计算、存储。比如常见的一个Web单体系统,其实也是一个分布式系统&#x…

Android监听消息(二)——电话及短信监听

学更好的别人, 做更好的自己。 ——《微卡智享》 本文长度为2747字,预计阅读6分钟 前言 前面一篇《Android监听消息(一)——应用消息捕获》我们使用NotificationListenerService实现了应用的消息监听,但是电话和短信是…

【花雕学AI】爆款ChatGPT的核心算法和技术逻辑到底是什么?

一、ChatGPT是一种基于GPT模型的聊天机器人 由OpenAI研究中心开发,于2022年11月30日发布。它可以根据用户的输入,生成自然、流畅、有趣的对话回复。它的技术逻辑主要是利用大规模的预训练语言模型(LLM),通过Transforme…