【C语言15】单链表,(对于二级指针与一级指针应用的详细讲述)

news2024/11/15 8:40:32

文章目录

  • 单链表
    • 1.单链表的介绍
    • 2.单链表的实现
        • 2.1.1单链表结点的创建与销毁
        • 2.1.2单链表尾插
        • 2.1.3单链表打印
        • 2.1.4尾删
        • 2.1.5头插
        • 2.1.6头删
        • 2.1.7查找
        • 2.1.8在pos位置之后插入数据
        • 2.1.9删除pos位置

单链表

1.单链表的介绍

链表是一种物理存储结构上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表
中的指针链接次序实现的 。

在上篇博客中,我们可以很清晰的看到顺序表的结构,但是链表不可以,链表的链接就是由指针指引的,

一个数据,他可能间隔着N个内存空间,但是它们却又是实实在在相连的,为了详细说明链表,我准备这么几张图片:
在这里插入图片描述

我们看到,单链表就像一个火车,由一个指针来确定他们不同节点的位置,从而串接起来,但是我们要了解一件事,图片中的箭头是虚拟的,是想象的,我们能确定下一个节点位置只有指针;

2.单链表的实现

#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<malloc.h>
typedef int SeDataType;
//定义结点
typedef struct SeqList
{
	SeDataType data;
	struct SeqList* next;
}SeNode;
//开辟节点
SeNode* BuySeqListNode(SeNode* phead, SeDataType x)
//销毁
void SeqListDestroy(SeNode** phead);
//打印
void SeqListPrint(SeNode* phead);
//尾插
void SeqListPushBack(SeNode** phead, SeDataType x);
//尾删
void SeqLIstPopBack(SeNode** phead);
//头插
void SeqListPushFront(SeNode** phead, SeDataType x);
//头删
void SeqListPopFront(SeNode** phead);
//pos位置之后插入
void SeqListInsterAfter(SeNode* pos, SeDataType x);
//删除pos位置
void SeqListEraseAfter(SeNode* pos);

为了实现单链表,我们需要实现以上接口

2.1.1单链表结点的创建与销毁

//初始化
SeNode* BuySeqListNode(SeDataType x)
{
	SeNode* newnode = (SeNode*)malloc(sizeof(SeNode));//创建结点
	if (newnode == NULL)//判断结点是否生成成功
	{
		perror("BuySeqListNode");
		exit(-1);
	}
	newnode->data = x;//赋值
	newnode->next = NULL;
	return newnode;//返回结点地址
}
//销毁
void SeqListDestroy(SeNode** phead)
{
	assert(phead);//判断是否为空
	while (*phead)//循环free空间
	{
		SeNode* next = (*phead)->next;//记录下一个节点,避免链接丢失
		free(*phead);//释放
		*phead = next;
	}
	*phead = NULL;//置空
}

当读完这串代码后,我们会发现这两个函数使用了完全不一样的指针类型.开辟节点使用的是一级指针,销毁结点使用的是二级指针.要注意,这是本篇博客难度最高的知识点,考验各位对指针的理解程度

在这里插入图片描述

在调用PushBack函数后,我们成功创建了一个节点node,我们在此时这个结点是孤立的
在这里插入图片描述

那么如何让让plist和node链接起来呢.那就是指针.,在此时,如果我们想要用pilst链接node,必须传递plist的地址,只有传递地址才能让plist的指向改变.如果不传递地址,后续操作只是一份临时拷贝

此时,一个纠结点就出现了.我plist本事就是指针,为什么要传递指针的地址呢.

我们来看一张图片

这张图生动的展示了指针本质上的区别.指针也是一种变量,是变量就会有地址.想要改变变量,就必须通过地址改变;在对plist进行修改的时候,虽然plist就是指针,但想要改变他存贮的值,就必须传递本身的地址,这就是为什么传递二级指针的原因.

2.1.2单链表尾插

如何进行尾插操作呢,我们要想明白一件事情,在我们创建的Sqnode类型中, next指向下一个结点.所以,如果我们想要尾插,必须找到next的前一个结点进行链接

void SeqListPushBack(SeNode** phead, SeDataType x)
{
	assert(phead);//判断指针是否为空
	SeNode* node = BuySeqListNode(x);//开辟节点
	if (*phead == NULL)//如果*phead为空,代表链表为空,之间赋值替换即可
	{
		*phead = node;
	}
	else
	{
		SeNode* tail = *phead;
		while (tail->next != NULL)//如果不为空,则遍历链表,在最后一个结点进行链接
		{
			tail = tail->next;
		}
		tail->next = node;
	}
}

此时,我们完成了尾插接口的实现,如何判断程序是否正确呢,我们可以通过调试直观地观察,也可以提前将打印接口实现观察,我们使用实现打印接口.

2.1.3单链表打印

应为我们只是要打印而无需任何改变指针的操作,所以只需要传递一级指针遍历整个数组即可

void SeqListPrint(SeNode* phead)
{
	SeNode* cur = phead;//记录位置
	while (cur)
	{
		printf("%d ", cur->data);//打印
		cur = cur->next;//赋值遍历
	}
}

在这里插入图片描述

程序正确,成功运行

2.1.4尾删

尾删的操作与尾插类似,不同的是我们需要遍历到倒数第二个结点,通过倒数第二个节点的next来释放最后一个节点达成尾删操作.因为需要改变内容,所以依旧传递二级指针
在这里插入图片描述

void SeqListPopBack(SeNode** phead)
{
	assert(phead);//判断指针是否为空
	assert(*phead);//判断指针指向的内容是否为空
	if ((*phead)->next == NULL)//如果只有一个节点,直接释放
	{
		free(*phead);
		*phead = NULL;
	}
	else
	{
		SeNode* tail = *phead;
		while (tail->next->next != NULL)//如果多个,遍历到末尾的前一个释放
		{
			tail = tail->next;
		}
		free(tail->next);
		tail->next = NULL;                       
	}
}

在这里插入图片描述

2.1.5头插

头插需要注意的是对于指针的操作,在有多个节点时,需要考虑如何在头插的同时链接原头结点

而在一个节点是直接替换赋值即可.

在这里插入图片描述

void SeqListPushFront(SeNode** phead, SeDataType x)
{
	assert(phead);//判断指针是否为空
	SeNode* newnode = BuySeqListNode(x);//创建新节点
	if (*phead == NULL)//当只有一个节点的时候,直接赋值
	{
		*phead = newnode;
	}
	else//多个节点是先链接在赋值
	{
		newnode->next = *phead;
		*phead = newnode;
	}
}

在这里插入图片描述

运行成功

2.1.6头删

头删要注意的与头插类似,直接上图
在这里插入图片描述

//头删
void SeqListPopFront(SeNode** phead)
{
	assert(phead);//判断指针是否为空
	assert(*phead);//判断指针指向的内容是否为空
	if ((*phead)->next == NULL)//只有一个节点时,直接释放
	{
		free(*phead);
		*phead = NULL;
	}
	else//多个节点时,记录新头结点,释放原头结点
	{	
		SeNode* pphead = (*phead)->next;
		free(*phead);
		*phead = pphead;
	}
}

在这里插入图片描述

运行成功

2.1.7查找

该接口原理与打印接口相同,同是遍历链表,不同点为该函数会返回一个地址

SeNode* SeqListFind(SeNode* phead,SeDataType x)
{
	assert(phead);//判断指针是否为空
	SeNode* cur = phead;//赋值遍历
	while (cur->next != NULL)
	{
		if (cur->data == x)//判断相等
		{
			return cur;//相等返回地址
		}
		cur = cur->next;
	}
	return NULL;	//不等返回NULL;
}

在这里插入图片描述

2.1.8在pos位置之后插入数据

在这里插入图片描述

void SeqListInsterAfter(SeNode**phead,SeNode* pos, SeDataType x)
{
	assert(pos);//判断指针是否为空
	assert(*phead);
	if (pos == *phead)//如果相等,就是头插
	{
		SeqListPushFront(phead,x);
	}
	else
	{
		SeNode* node = BuySeqListNode(x);
		SeNode* pphead = pos->next;//记录原结点链接的数据
		node->next = pphead;//链接
		pos->next = node;
	}
}

在这里插入图片描述

修改成功

2.1.9删除pos位置

在这里插入图片描述

void SeqListEraseAfter(SeNode** phead, SeNode* pos)
{
	assert(pos);//判断空指针
	if (pos==*phead)//如果相等就是头删
	{
		SeqListPopFront(phead);
	}
	else
	{
		SeNode* cur = *phead;
		while (cur->next != pos)//记录pos的前一个位置
		{
			cur = cur->next;
		}
		cur->next = pos->next;//链接
		free(pos);//释放
		pos = NULL;
	}
}

完整代码

//SeqList.h
#define _CRT_SECURE_NO_WARNINGS 1
#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<malloc.h>
typedef int SeDataType;
//定义结点
typedef struct SeqList
{
	SeDataType data;
	struct SeqList* next;
}SeNode;
//初始化
void SeqListInit(SeNode** phead);
//销毁
void SeqListDestroy(SeNode** phead);
//打印
void SeqListPrint(SeNode* phead);
//尾插
void SeqListPushBack(SeNode** phead, SeDataType x);
//尾删
void SeqListPopBack(SeNode** phead);
//头插
void SeqListPushFront(SeNode** phead, SeDataType x);
//头删
void SeqListPopFront(SeNode** phead);
//pos位置之后插入
void SeqListInsterAfter(SeNode** phead,SeNode* pos, SeDataType x);
//删除pos位置
void SeqListEraseAfter(SeNode** phead, SeNode* pos);

//SeqList.c
#define _CRT_SECURE_NO_WARNINGS 1
#include"SeqList.h"
//初始化
SeNode* BuySeqListNode(SeDataType x)
{
	SeNode* newnode = (SeNode*)malloc(sizeof(SeNode));//创建结点
	if (newnode == NULL)//判断结点是否生成成功
	{
		perror("BuySeqListNode");
		exit(-1);
	}
	newnode->data = x;//赋值
	newnode->next = NULL;
	return newnode;//返回结点地址
}
//销毁
void SeqListDestroy(SeNode** phead)
{
	assert(phead);//判断是否为空
	while (*phead)//循环free空间
	{
		SeNode* next = (*phead)->next;//记录下一个节点,避免链接丢失
		free(*phead);//释放
		*phead = next;
	}
	*phead = NULL;//置空
}
//打印
void SeqListPrint(SeNode* phead)
{
	SeNode* cur = phead;//记录位置
	while (cur)
	{
		printf("%d->", cur->data);//打印
		cur = cur->next;//赋值遍历
	}
	printf("NULL\n");
}
//尾插
void SeqListPushBack(SeNode** phead, SeDataType x)
{
	assert(phead);//判断指针是否为空
	SeNode* node = BuySeqListNode(x);//开辟节点
	if (*phead == NULL)//如果*phead为空,代表链表为空,之间赋值替换即可
	{
		*phead = node;
	}
	else
	{
		SeNode* tail = *phead;
		while (tail->next != NULL)//如果不为空,则遍历链表,在最后一个结点进行链接
		{
			tail = tail->next;
		}
		tail->next = node;
	}
}
//尾删
void SeqListPopBack(SeNode** phead)
{
	assert(phead);//判断指针是否为空
	assert(*phead);//判断指针指向的内容是否为空
	if ((*phead)->next == NULL)//如果只有一个节点,直接释放
	{
		free(*phead);
		*phead = NULL;
	}
	else
	{
		SeNode* tail = *phead;
		while (tail->next->next != NULL)//如果多个,遍历到末尾的前一个释放
		{
			tail = tail->next;
		}
		free(tail->next);
		tail->next = NULL;                       
	}
}
//头插
void SeqListPushFront(SeNode** phead, SeDataType x)
{
	assert(phead);//判断指针是否为空
	SeNode* newnode = BuySeqListNode(x);//创建新节点
	if (*phead == NULL)//当只有一个节点的时候,直接赋值
	{
		*phead = newnode;
	}
	else//多个节点是先链接在赋值
	{
		newnode->next = *phead;
		*phead = newnode;
	}
}
//头删
void SeqListPopFront(SeNode** phead)
{
	assert(phead);//判断指针是否为空
	assert(*phead);//判断指针指向的内容是否为空
	if ((*phead)->next == NULL)//只有一个节点时,直接释放
	{
		free(*phead);
		*phead = NULL;
	}
	else//多个节点时,记录新头结点,释放原头结点
	{	
		SeNode* pphead = (*phead)->next;
		free(*phead);
		*phead = pphead;
	}
}
SeNode* SeqListFind(SeNode* phead,SeDataType x)
{
	assert(phead);//判断指针是否为空
	SeNode* cur = phead;//赋值遍历
	while (cur->next != NULL)
	{
		if (cur->data == x)//判断相等
		{
			return cur;//相等返回地址
		}
		cur = cur->next;
	}
	return NULL;	//不等返回NULL;
}
//pos位置之后插入
void SeqListInsterAfter(SeNode**phead,SeNode* pos, SeDataType x)
{
	assert(pos);//判断指针是否为空
	assert(*phead);
	if (pos == *phead)//如果相等,就是头插
	{
		SeqListPushFront(phead,x);
	}
	else
	{
		SeNode* node = BuySeqListNode(x);
		SeNode* pphead = pos->next;//记录原结点链接的数据
		node->next = pphead;//链接
		pos->next = node;
	}
}
//删除pos位置
void SeqListEraseAfter(SeNode** phead, SeNode* pos)
{
	assert(pos);//判断空指针
	if (pos==*phead)//如果相等就是头删
	{
		SeqListPopFront(phead);
	}
	else
	{
		SeNode* cur = *phead;
		while (cur->next != pos)//记录pos的前一个位置
		{
			cur = cur->next;
		}
		cur->next = pos->next;//链接
		free(pos);//释放
		pos = NULL;
	}
}


//SeqListTest.c
#define _CRT_SECURE_NO_WARNINGS 1
#include"SeqList.h"
void SeqListTest()
{
	SeNode* plist = NULL;
	SeqListPushFront(&plist, 5);
	SeqListPushFront(&plist, 4);
	SeqListPushFront(&plist, 3);
	SeqListPushFront(&plist, 2);
	SeqListPushFront(&plist, 1);
	SeqListPushFront(&plist, 0);
	SeqListPrint(plist);
	SeNode* ptr = SeqListFind(plist, 3);
	if (ptr != NULL)
	{
		SeqListEraseAfter(&plist, ptr);
	}
	else
	{
		printf("数据有误\n");
	}
	SeqListPrint(plist);
	/*SeNode* ptr = SeqListFind(plist, 3);
	if (ptr != NULL)
	{
		printf("%p %d", ptr,ptr->data);
	}
	else
	{
		printf("数据有误\n");
	}*/
	//SeqListPopFront(&plist);
	//SeqListPopFront(&plist);
	//SeqListPopFront(&plist);
	//SeqListPopFront(&plist);
	//SeqListPopFront(&plist);
	//SeqListPrint(plist);
	//SeqListPopFront(&plist);
	//SeqListPrint(plist);
	/*SeqListPushBack(&plist, 1);
	SeqListPushBack(&plist, 2);
	SeqListPushBack(&plist, 3);
	SeqListPushBack(&plist, 4);
	SeqListPushBack(&plist, 5);
	SeqListPrint(plist);
	SeqListPopBack(&plist);
	SeqListPrint(plist);
	SeqListPopBack(&plist);
	SeqListPrint(plist);
	SeqListPopBack(&plist);
	SeqListPrint(plist);
	SeqListPopBack(&plist);
	SeqListPrint(plist);
	SeqListPopBack(&plist);
	SeqListPrint(plist);
	SeqListDestroy(&plist);*/

}
int main()
{
	SeqListTest();
	return 0;
}

ont(&plist);

//SeqListPrint(plist);
/SeqListPushBack(&plist, 1);
SeqListPushBack(&plist, 2);
SeqListPushBack(&plist, 3);
SeqListPushBack(&plist, 4);
SeqListPushBack(&plist, 5);
SeqListPrint(plist);
SeqListPopBack(&plist);
SeqListPrint(plist);
SeqListPopBack(&plist);
SeqListPrint(plist);
SeqListPopBack(&plist);
SeqListPrint(plist);
SeqListPopBack(&plist);
SeqListPrint(plist);
SeqListPopBack(&plist);
SeqListPrint(plist);
SeqListDestroy(&plist);
/

}
int main()
{
SeqListTest();
return 0;
}



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

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

相关文章

科学家用ChatGPT写完1篇论文仅用1小时!多所高校撤销禁令

自2022年11月发布以来&#xff0c;许多人都在使用ChatGPT来帮助他们完成工作&#xff0c;各行各业的人都在使用&#xff0c;从撰写营销材料&#xff0c;到起草电子邮件&#xff0c;再到生成报告。 ChatGPT作为一种人工智能工具&#xff0c;在科研中也显示非常大的应用潜力&…

汽车行业 Y 公司对接斯堪尼亚 SCANIA EDI 项目案例

斯堪尼亚是一家来自瑞典的重型车辆制造公司&#xff0c;成立于1891年&#xff0c;总部位于斯德哥尔摩&#xff0c;主要专注于生产卡车、客车和工业发动机&#xff0c;以及相应的服务与解决方案。斯堪尼亚的产品以其高品质、可靠性和先进技术而闻名。其卡车广泛应用于货运和运输…

大文件传输过程中的网络拥塞控制方法研究

随着网络技术的进步&#xff0c;我们在工作和生活中经常需要传输大文件。但是在实际的文件传输过程中&#xff0c;网络拥塞问题一直是困扰着我们和网络服务商的一个难题。接下来将从网络拥塞的原因、影响以及控制方法等方面详细介绍大文件传输过程中的网络拥塞控制方法。 一、网…

Gnomon室外照明学习

阴影 复制4个 15 开启主光 复制选择45度的那组灯光 关闭阴影 灯光颜色吸取地面 对比 组 X和Z平移归0 整体旋转 太阳调整 吸取图片上面的颜色&#xff0c;天空那组灯 复制一个

【Vscode | R | Win】R Markdown转html记录-Win

Rmd文件转html R语言环境Vscode扩展安装及配置配置radian R依赖包pandoc安装配置pandoc环境变量验证是否有效转rmd为html 注意本文代码块均为R语言代码&#xff0c;在R语言环境下执行即可 R语言环境 官网中去下载R语言安装包以及R-tool 可自行搜寻教程 无需下载Rstudio Vscod…

面试题 -- 客户端安全性和框架设计

文章目录 1. 客户端安全性处理方式2. sip是什么&#xff1f;3. 有些图片加载的比较慢怎么处理&#xff1f;你是怎么优化程序的性能的&#xff1f;4. 实现过一个框架或者库以供别人使用么&#xff1f;5. App需要加载超大量的数据&#xff0c;给服务器发送请求&#xff0c;但是服…

如何测试Linux内核

目录 概述 LTP 构建系统 C测试用例 参考资料 Autotest Kmemleak Kmemcheck Linaro LAVA 调试器 GDB KGDB 设备驱动测试 资料获取方法 概述 在本文中&#xff0c;我们将讨论用于测试Linux内核的各种框架和工具。首先&#xff0c;我们将介绍LTP( Linux Test Proje…

Ribbon 启用规则,SelectionCountRule规则在Classic界面下不生效,只有在UCI界面下才生效

Ribbon 启用规则&#xff0c;SelectionCountRule规则在Classic界面下不生效&#xff0c;只有在UCI界面下才生效。

Python pygame(GUI编程)模块最完整教程(7)

上一篇文章&#xff1a; Python pygame(GUI编程)模块最完整教程&#xff08;6&#xff09;_Python-ZZY的博客-CSDN博客 总目录&#xff1a; README.md Python-ZZY/Python-Pygame最完整教程 - Gitee.com 21 OpenGL与Pygame 不会OpenGL的读者可以跳过本章节。 21.1 OpenGL简…

后端一次返回大量数据,前端做分页处理

问题描述&#xff1a;后端接口返回大量数据&#xff0c;没有做分页处理&#xff0c;不支持传参pageNum&#xff0c;pageSize 本文为转载文章&#xff0c;原文章&#xff1a;后端一次返回大量数据&#xff0c;前端做分页处理 1.template中 分页 <el-paginationsize-chang…

局域网内主机ping不通,但是可以调用对方http接口(防火墙阻止了icmp协议)(关闭防火墙或者启用ICMP回显请求(ICMPv4-In))

文章目录 背景可能的原因问题排查及解决 背景 局域网内有一台主机&#xff0c;ping它ping不通&#xff0c;但是可以调用它的http接口&#xff0c;很诡异。。。 可能的原因 可能的原因有以下几种&#xff1a; 防火墙设置&#xff1a;局域网内的主机可能设置了防火墙&#xff…

【Unity3D日常开发】Unity3D中Package Manager加载不出来插件包或者加载出来后无法Install的问题

推荐阅读 CSDN主页GitHub开源地址Unity3D插件分享简书地址我的个人博客 大家好&#xff0c;我是佛系工程师☆恬静的小魔龙☆&#xff0c;不定时更新Unity开发技巧&#xff0c;觉得有用记得一键三连哦。 一、前言 今天在新电脑上打开Unity3D的Package Manager&#xff08;包管…

<MyBatis>前台传参多个条件查询方式(传数组或者拼接字符串)

方式一&#xff1a;前台传参为数组&#xff0c;后台SQ查询案例&#xff1a; 一般为多选场景&#xff1a;查询&#xff1b; 举例如下&#xff1a; 传值&#xff1a;“status” : [“保存”,“关闭”], 不传值&#xff1a;“status”: [], 传给后台&#xff1a; 控制层&#xff1…

清洁力好的洗地机有哪些品牌、清洁力好的洗地机盘点

清洁力好的清洁工具有很多&#xff0c;但是想要清洁力好的并且又省心省力&#xff0c;快捷高效的洗地机可以说是榜上有名&#xff01;在清洁的时候&#xff0c;洗地机的作用相比传统清洁工具使用更加的便捷&#xff0c;并且清洁力不比传统清洁工具差&#xff0c;同时还衍生了更…

八、seata使用及源码分析

一、数据库事务ACID特性 基础概念&#xff1a;事务ACID A&#xff08;Atomic&#xff09;&#xff1a;原子性&#xff0c;构成事务的所有操作&#xff0c;要么都执行完成&#xff0c;要么全部不执行&#xff0c;不可能出现部分成功部分失 败的情况。C&#xff08;Consistency…

【雕爷学编程】Arduino动手做(93)--- 0.96寸OLED液晶屏模块17

37款传感器与执行器的提法&#xff0c;在网络上广泛流传&#xff0c;其实Arduino能够兼容的传感器模块肯定是不止这37种的。鉴于本人手头积累了一些传感器和执行器模块&#xff0c;依照实践出真知&#xff08;一定要动手做&#xff09;的理念&#xff0c;以学习和交流为目的&am…

使用Java IO进行压缩和解压缩 | ZIP和GZIP的实现

文章目录 一、概述二、ZIP2.1 ZIP格式介绍2.2 Java IO中的ZIP库和类介绍2.3 ZIP压缩文件2.4 ZIP解压缩文件 三、GZIP3.1 GZIP格式介绍3.2 Java IO中的GZIP库和类介绍3.3 GZIP压缩文件3.4 GZIP解压缩文件 四、压缩和解压缩的注意事项4.1 选择合适的压缩格式和方法4.2 处理大文件…

山西电力市场日前价格预测【2023-07-28】

日前价格预测 预测明日&#xff08;2023-07-28&#xff09;山西电力市场全天平均日前电价为349.59元/MWh。其中&#xff0c;最高日前电价为378.84元/MWh&#xff0c;预计出现在20: 15。最低日前电价为321.82元/MWh&#xff0c;预计出现在13: 15。 价差方向预测 1&#xff1a;实…

【Ajax】笔记-jsonp实现原理

JSONP JSONP是什么 JSONP(JSON With Padding),是一个非官方的跨域解决方案&#xff0c;纯粹凭借程序员的聪明才智开发出来的&#xff0c;只支持get请求。JSONP 怎么工作的&#xff1f; 在网页有一些标签天生具有跨域能力&#xff0c;比如&#xff1a;img link iframe script. …

为什么说RL 是强化学习的技巧?

一、说明 深度学习&#xff08;DL&#xff09;很难训练&#xff0c;强化学习&#xff08;RL&#xff09;要更难。在早期开发中&#xff0c;遵循与 DL 相同的策略&#xff1a;保持简单&#xff01;消除任何妨碍您的花里胡哨的东西&#xff0c;并将不确定性降至最低。 具体到RL&a…