C#进阶学习(四)单向链表和双向链表,循环链表(上)单向链表

目录

前置知识:

一、链表中的结点类LinkedNode

1、申明字段节点类:

2、申明属性节点类:

二、两种方式实现单向链表

①定框架:

②增加元素的方法:因为是单链表,所以增加元素一定是只能在末尾添加元素,即在头结点后面添加元素

③删除元素的方法:删除链表中第一个符合删除目标值的节点 

④查找节点是否存在,这个就很简单,直接遍历一遍就好了。

 ⑤更新某一个节点的数据

三、测试 

测试接口:

写一个测试函数:

开始测试:

测试结果:


前置知识:

        数据结构:

数据结构:数据元素之间的相互关系
常用的数据结构
数组、链表、栈、队列、树、图,堆,散列表

         线性表:

线性表是一种数据结构是由n个具有相同特性的数据元素的有限序列
例如:数组、链表、栈、队列,ArrayList

        顺序存储:

数组、Stack、Queue、ArrayList->顺序存储
只是 数组、Stack、Queue、ArrayList的组织规则不同而已
顺序存储
用一组地址连续的存储单元依次存储线性表的各个元素,数据元素之间的逻辑关系由存储单元的邻接关系来体现。内存地址连续,一整片的内存

顺序存储链式存储 是数据结构中的两种存储方式  

        链式存储:

单向链表、双向链表、循环链表->链式存储
链式存储(链接存储)
用一组任意的存储单元存储线性表中的各个数据元素,内存地址不连续跳跃式的。

如需了解更多,可看这一篇文章:

线性表的相关知识

  好的,回归主线,今天咱们学习的重点是单向链表以及双向链表,循环链表

一、链表中的结点类LinkedNode

         什么是LinkedNode呢,他有什么作用呢?他其实就是组成链表的基本单位,链表就是一个个的LinkedNode串起来的,只不过串的方式不太一样。下面代码示例中不一定使用的是LinkedNode这个名字,使用的是其他的名字不过没关系,学习而已。例如:

        在单向链表中:每个链表结点有一个指向下一个链表结点的类似于C语言中的指针的东西,就是说明了,当前节点的下一个就是你,二者建立了联系。对于单向链表中,第一个结点,我们称之为头结点,因为他只能向后指,不能朝前看,所以每次寻找某一个元素,需要进行遍历,而且你永远找不到自己的上一个元素是什么。于是有了双向链表

        在双向链表中:每个链表节点存有两个指针,一个是指向当前结点的上一个结点,一个是指向当前结点的下一个结点,其余的和单向链表相同。

        所谓循环链表:就是在单链表中,将最后一个结点的下一个指向第一个结点。

好的,接下来我们实现这个节点类:

     单向链表的节点类:

两种定义方式:

1、申明字段节点类:

/// <summary>
/// 单向链表节点定义(字段版本)
/// </summary>
/// <typeparam name="T">泛型数据类型</typeparam>
public class ListNode_Field<T>
{// 节点存储的数据(字段)public T data;// 指向下一个节点的指针(字段)// "?" 表示这是一个可空类型,允许值为 nullpublic ListNode_Field<T>? next;/// <summary>/// 构造函数/// </summary>/// <param name="val">节点数据</param>public ListNode_Field(T val){data = val;next = null;}
}

2、申明属性节点类:

/// <summary>
/// 单向链表节点定义(属性版本)
/// </summary>
/// <typeparam name="T">泛型数据类型</typeparam>
public class SingleListNode<T>
{// 节点存储的数据(属性)public T Data { get; set; }// 指向下一个节点的指针(属性)// "?" 表示这是一个可空类型,允许值为 nullpublic SingleListNode<T>? Next { get; set; }/// <summary>/// 构造函数/// </summary>/// <param name="data">节点数据</param>public SingleListNode(T data){Data = data;Next = null; // 初始化时指针置空}
}

         这两种方式任意选择一种进行申明即可,推荐使用属性,因为可以自己处理的手段更多。

二、两种方式实现单向链表

        好的接下来我们实现一个单向链表,因为有了这些基本节点类,所以才会有下面的代码。同样我们会使用属性节点类和字段节点类进行说明。其实都差不多的。

        总的设计思路:

        1、提供一个头结点

        2、利用这个头结点进行增删改查

        接下来我们一一实现:下面是一个利用字段节点声明的单向链表

①定框架:

    public class SingleLinkedList_Field<T>{//设置一个私有头结点private ListNode_Field<T>? head;}

②增加元素的方法:因为是单链表,所以增加元素一定是只能在末尾添加元素,即在头结点后面添加元素

        步骤:

(1)先申明一个新的节点

(2)判断头结点是否为空,为空则添加的元素就是头结点元素,反之遍历找到最后一个节点,然后将最后一个结点的next指向当前新创造的节点

/// <summary>
/// 在链表尾部添加新节点
/// </summary>
public void Add(T data)
{ListNode_Field<T> newNode = new ListNode_Field<T>(data);if (head == null){head = newNode;return;}// 遍历链表找到最后一个节点ListNode_Field<T> current = head;while (current.next != null){current = current.next;}current.next = newNode; // 直接操作字段
}

        当然这个添加元素,你也可以想想怎么在中间插入一个元素,思想是将上一个的next指向插入元素,插入元素的next指向上一个元素的下一个 

③删除元素的方法:删除链表中第一个符合删除目标值的节点 

        步骤:

(1)先看有没有头结点,没有头结点删除个屁啊

(2)然后看删除的是不是头结点,是的话直接将头结点的next指向下一个就好啦

(3)不是头结点的话,就稍微有一点点麻烦,需要先遍历,和Add方法差不多的

/// <summary>
/// 删除第一个匹配的节点
/// </summary>
public bool Remove(T data)
{if (head == null) return false;// 处理头节点匹配的情况if (head.data != null && head.data.Equals(data)){head = head.next; // 直接操作字段return true;}ListNode_Field<T> current = head;while (current.next != null){if (current.next.data != null && current.next.data.Equals(data)){current.next = current.next.next; // 直接操作字段return true;}current = current.next;}return false;
}

④查找节点是否存在,这个就很简单,直接遍历一遍就好了。

/// <summary>
/// 查找节点是否存在
/// </summary>
public bool Contains(T data)
{ListNode_Field<T>? current = head;while (current != null){if (current.data != null && current.data.Equals(data)){return true;}current = current.next;}return false;
}

 ⑤更新某一个节点的数据

        步骤:

(1)找到该节点

(2)操作该节点的数据

/// <summary>
/// 更新第一个匹配的节点的值
/// </summary>
public bool Update(T oldData, T newData)
{ListNode_Field<T>? node = FindNode(oldData);if (node == null) return false;node.data = newData; // 直接操作字段return true;
}/// <summary>
/// 辅助方法:查找指定数据的节点
/// </summary>
private ListNode_Field<T>? FindNode(T data)
{ListNode_Field<T>? current = head;while (current != null){if (current.data != null && current.data.Equals(data)){return current;}current = current.next;}return null;
}

        好的,那么我们就完成了一个最简单的单向链表的数据结构!

附上使用属性申明的单行链表,是一样的:

    /// <summary>/// 单向链表实现(属性版本)/// </summary>/// <typeparam name="T">泛型数据类型</typeparam>public class SingleLinkedList_Property<T> : ISingleLinkedList<T>{// 头节点(私有属性)private SingleListNode<T>? head;/// <summary>/// 在链表尾部添加新节点/// </summary>/// <param name="data">要添加的数据</param>public void Add(T data){// 显式声明类型(不使用 var)SingleListNode<T> newNode = new SingleListNode<T>(data);if (head == null){head = newNode; // 链表为空时,新节点作为头节点return;}// 遍历链表找到最后一个节点SingleListNode<T> current = head;while (current.Next != null){current = current.Next;}current.Next = newNode; // 将新节点链接到尾部}/// <summary>/// 删除第一个匹配的节点/// </summary>/// <param name="data">要删除的数据</param>/// <returns>是否删除成功</returns>public bool Remove(T data){if (head == null) return false;// 处理头节点匹配的情况if (head.Data != null && head.Data.Equals(data)){head = head.Next; // 头节点指向下一个节点return true;}// 遍历链表查找匹配的节点SingleListNode<T> current = head;while (current.Next != null){if (current.Next.Data != null && current.Next.Data.Equals(data)){current.Next = current.Next.Next; // 跳过匹配的节点return true;}current = current.Next;}return false;}/// <summary>/// 查找节点是否存在/// </summary>/// <param name="data">要查找的数据</param>/// <returns>是否存在</returns>public bool Contains(T data){SingleListNode<T>? current = head;while (current != null){if (current.Data != null && current.Data.Equals(data)){return true;}current = current.Next;}return false;}/// <summary>/// 更新第一个匹配的节点的值/// </summary>/// <param name="oldData">旧数据</param>/// <param name="newData">新数据</param>/// <returns>是否更新成功</returns>public bool Update(T oldData, T newData){SingleListNode<T>? node = FindNode(oldData);if (node == null) return false;node.Data = newData; // 直接修改节点的数据return true;}/// <summary>/// 辅助方法:查找指定数据的节点/// </summary>private SingleListNode<T>? FindNode(T data){SingleListNode<T>? current = head;while (current != null){if (current.Data != null && current.Data.Equals(data)){return current;}current = current.Next;}return null;}}

三、测试 

        测试部分呢,因为两种都差不多,所以我们使用一个接口,让他们都实现里面的方法,然后统一测试

测试接口:

/// <summary>
/// 统一接口(便于测试不同版本的链表)
/// </summary>
public interface ISingleLinkedList<T>
{void Add(T data);bool Remove(T data);bool Contains(T data);bool Update(T oldData, T newData);
}

两个链表只要继承了这个接口就好

写一个测试函数:

static void TestLinkedList<T>(T list) where T : ISingleLinkedList<int>
{// 添加节点list.Add(1);list.Add(2);list.Add(3);Console.WriteLine("添加 1, 2, 3 后链表内容应为:1 -> 2 -> 3");// 测试查找Console.WriteLine("查找 2: " + list.Contains(2)); // 应输出 TrueConsole.WriteLine("查找 4: " + list.Contains(4)); // 应输出 False// 测试删除list.Remove(2);Console.WriteLine("删除 2 后链表内容应为:1 -> 3");Console.WriteLine("查找 2: " + list.Contains(2)); // 应输出 False// 测试更新list.Update(3, 4);Console.WriteLine("更新 3 为 4 后链表内容应为:1 -> 4");Console.WriteLine("查找 4: " + list.Contains(4)); // 应输出 True
}

开始测试:

 static void Main(string[] args){// 测试属性版本链表Console.WriteLine("测试属性版本链表:");TestLinkedList(new SingleLinkedList_Property<int>());// 测试字段版本链表Console.WriteLine("\n测试字段版本链表:");TestLinkedList(new SingleLinkedList_Field<int>());}

测试结果:

 如果再讲双向链表和循环链表,会显得很杂乱,我们将会在下一篇文章讨论,诸位共勉!

附:本文所有代码

namespace 单向链表
{/// <summary>/// 单向链表节点定义(属性版本)/// </summary>/// <typeparam name="T">泛型数据类型</typeparam>public class SingleListNode<T>{// 节点存储的数据(属性)public T Data { get; set; }// 指向下一个节点的指针(属性)// "?" 表示这是一个可空类型,允许值为 null(解决 CS8618 警告)public SingleListNode<T>? Next { get; set; }/// <summary>/// 构造函数/// </summary>/// <param name="data">节点数据</param>public SingleListNode(T data){Data = data;Next = null; // 初始化时指针置空}}/// <summary>/// 单向链表节点定义(字段版本)/// </summary>/// <typeparam name="T">泛型数据类型</typeparam>public class ListNode_Field<T>{// 节点存储的数据(字段)public T data;// 指向下一个节点的指针(字段)// "?" 表示这是一个可空类型,允许值为 nullpublic ListNode_Field<T>? next;/// <summary>/// 构造函数/// </summary>/// <param name="val">节点数据</param>public ListNode_Field(T val){data = val;next = null;}}internal class Program{static void Main(string[] args){// 测试属性版本链表Console.WriteLine("测试属性版本链表:");TestLinkedList(new SingleLinkedList_Property<int>());// 测试字段版本链表Console.WriteLine("\n测试字段版本链表:");TestLinkedList(new SingleLinkedList_Field<int>());}static void TestLinkedList<T>(T list) where T : ISingleLinkedList<int>{// 添加节点list.Add(1);list.Add(2);list.Add(3);Console.WriteLine("添加 1, 2, 3 后链表内容应为:1 -> 2 -> 3");// 测试查找Console.WriteLine("查找 2: " + list.Contains(2)); // 应输出 TrueConsole.WriteLine("查找 4: " + list.Contains(4)); // 应输出 False// 测试删除list.Remove(2);Console.WriteLine("删除 2 后链表内容应为:1 -> 3");Console.WriteLine("查找 2: " + list.Contains(2)); // 应输出 False// 测试更新list.Update(3, 4);Console.WriteLine("更新 3 为 4 后链表内容应为:1 -> 4");Console.WriteLine("查找 4: " + list.Contains(4)); // 应输出 True}}/// <summary>/// 统一接口(便于测试不同版本的链表)/// </summary>public interface ISingleLinkedList<T>{void Add(T data);bool Remove(T data);bool Contains(T data);bool Update(T oldData, T newData);}/// <summary>/// 单向链表实现(属性版本)/// </summary>/// <typeparam name="T">泛型数据类型</typeparam>public class SingleLinkedList_Property<T> : ISingleLinkedList<T>{// 头节点(私有属性)private SingleListNode<T>? head;/// <summary>/// 在链表尾部添加新节点/// </summary>/// <param name="data">要添加的数据</param>public void Add(T data){// 显式声明类型(不使用 var)SingleListNode<T> newNode = new SingleListNode<T>(data);if (head == null){head = newNode; // 链表为空时,新节点作为头节点return;}// 遍历链表找到最后一个节点SingleListNode<T> current = head;while (current.Next != null){current = current.Next;}current.Next = newNode; // 将新节点链接到尾部}/// <summary>/// 删除第一个匹配的节点/// </summary>/// <param name="data">要删除的数据</param>/// <returns>是否删除成功</returns>public bool Remove(T data){if (head == null) return false;// 处理头节点匹配的情况if (head.Data != null && head.Data.Equals(data)){head = head.Next; // 头节点指向下一个节点return true;}// 遍历链表查找匹配的节点SingleListNode<T> current = head;while (current.Next != null){if (current.Next.Data != null && current.Next.Data.Equals(data)){current.Next = current.Next.Next; // 跳过匹配的节点return true;}current = current.Next;}return false;}/// <summary>/// 查找节点是否存在/// </summary>/// <param name="data">要查找的数据</param>/// <returns>是否存在</returns>public bool Contains(T data){SingleListNode<T>? current = head;while (current != null){if (current.Data != null && current.Data.Equals(data)){return true;}current = current.Next;}return false;}/// <summary>/// 更新第一个匹配的节点的值/// </summary>/// <param name="oldData">旧数据</param>/// <param name="newData">新数据</param>/// <returns>是否更新成功</returns>public bool Update(T oldData, T newData){SingleListNode<T>? node = FindNode(oldData);if (node == null) return false;node.Data = newData; // 直接修改节点的数据return true;}/// <summary>/// 辅助方法:查找指定数据的节点/// </summary>private SingleListNode<T>? FindNode(T data){SingleListNode<T>? current = head;while (current != null){if (current.Data != null && current.Data.Equals(data)){return current;}current = current.Next;}return null;}}/// <summary>/// 单向链表实现(字段版本)/// </summary>/// <typeparam name="T">泛型数据类型</typeparam>public class SingleLinkedList_Field<T> :ISingleLinkedList<T>{// 头节点(私有字段)private ListNode_Field<T>? head;/// <summary>/// 在链表尾部添加新节点/// </summary>public void Add(T data){ListNode_Field<T> newNode = new ListNode_Field<T>(data);if (head == null){head = newNode;return;}// 遍历链表找到最后一个节点ListNode_Field<T> current = head;while (current.next != null){current = current.next;}current.next = newNode; // 直接操作字段}/// <summary>/// 删除第一个匹配的节点/// </summary>public bool Remove(T data){if (head == null) return false;// 处理头节点匹配的情况if (head.data != null && head.data.Equals(data)){head = head.next; // 直接操作字段return true;}ListNode_Field<T> current = head;while (current.next != null){if (current.next.data != null && current.next.data.Equals(data)){current.next = current.next.next; // 直接操作字段return true;}current = current.next;}return false;}/// <summary>/// 查找节点是否存在/// </summary>public bool Contains(T data){ListNode_Field<T>? current = head;while (current != null){if (current.data != null && current.data.Equals(data)){return true;}current = current.next;}return false;}/// <summary>/// 更新第一个匹配的节点的值/// </summary>public bool Update(T oldData, T newData){ListNode_Field<T>? node = FindNode(oldData);if (node == null) return false;node.data = newData; // 直接操作字段return true;}/// <summary>/// 辅助方法:查找指定数据的节点/// </summary>private ListNode_Field<T>? FindNode(T data){ListNode_Field<T>? current = head;while (current != null){if (current.data != null && current.data.Equals(data)){return current;}current = current.next;}return null;}}
}

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

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

相关文章

RK3588 Buildroot 串口测试工具

RK3588 Buildroot串口测试工具(含代码) 一、引言 1.1 目的 本文档旨在指导开发人员能快速测试串口功能 1.2 适用范围 本文档适用于linux 系统串口测试。 二、开发环境准备 2.1 硬件环境 开发板:RK3588开发板,确保其串口硬件连接正常,具备电源供应、调试串口等基本硬…

HOJ PZ

https://docs.hdoi.cn/deploy 单体部署 请到~/hoj-deploy/standAlone的目录下&#xff0c;即是与docker-compose.yml的文件同个目录下&#xff0c;该目录下有个叫hoj的文件夹&#xff0c;里面的文件夹介绍如下&#xff1a; hoj ├── file # 存储了上传的图片、上传的临…

EtherCAT 的优点与缺点

EtherCAT&#xff08;以太网控制自动化技术&#xff09;是一种高性能的工业以太网协议&#xff0c;广泛应用于实时自动化控制。以下是其核心优缺点分析&#xff1a; ​一、EtherCAT 的核心优点​ 1. ​超低延迟 & 高实时性​ ​原理​&#xff1a;采用"​Processing…

高并发多级缓存架构实现思路

目录 1.整体架构 3.安装环境 1.1 使用docket安装redis 1.2 配置redis缓存链接&#xff1a; 1.3 使用redisTemplate实现 1.4 缓存注解优化 1.4.1 常用缓存注解简绍 1.4.2 EnableCaching注解的使用 1.4.3使用Cacheable 1.4.4CachePut注解的使用 1.4.5 优化 2.安装Ngin…

Qt QML实现Windows桌面颜色提取器

前言 实现一个简单的小工具&#xff0c;使用Qt QML实现Windows桌面颜色提取器&#xff0c;实时显示鼠标移动位置的颜色值&#xff0c;包括十六进制值和RGB值。该功能在实际应用中比较常见&#xff0c;比如截图的时候&#xff0c;鼠标移动就会在鼠标位置实时显示坐标和颜色值&a…

vue3+vite 多个环境配置

同一套代码 再也不用在不同的环境里来回切换请求地址了 然后踩了一个坑 就是env的文件路径是在当前项目下 不是在views内 因为公司项目需求只有dev和pro两个环境 虽然我新增了3个 但是只在这两个里面配置了 .env是可以配置一些公共配置的 目前需求来说不需要 所以我也懒得配了。…

AI赋能PLC(一):三菱FX-3U编程实战初级篇

前言 在工业自动化领域&#xff0c;三菱PLC以其高可靠性、灵活性和广泛的应用场景&#xff0c;成为众多工程师的首选控制设备。然而&#xff0c;传统的PLC编程往往需要深厚的专业知识和经验积累&#xff0c;开发周期长且调试复杂。随着人工智能技术的快速发展&#xff0c;利用…

XSS 跨站Cookie 盗取表单劫持网络钓鱼溯源分析项目平台框架

漏洞原理&#xff1a;接受输入数据&#xff0c;输出显示数据后解析执行 基础类型&#xff1a;反射 ( 非持续 ) &#xff0c;存储 ( 持续 ) &#xff0c; DOM-BASE 拓展类型&#xff1a; jquery &#xff0c; mxss &#xff0c; uxss &#xff0c; pdfxss &#xff0c; flashx…

鸿蒙应用(医院诊疗系统)开发篇2·Axios网络请求封装全流程解析

一、项目初始化与环境准备 1. 创建鸿蒙工程 src/main/ets/ ├── api/ │ ├── api.ets # 接口聚合入口 │ ├── login.ets # 登录模块接口 │ └── request.ets # 网络请求核心封装 └── pages/ └── login.ets # 登录页面逻辑…

ADAS高级驾驶辅助系统详细介绍

ADAS&#xff08;高级驾驶辅助系统&#xff09;核心模块&#xff0c;通过 “监测→预警→干预” 三层逻辑提升行车安全。用户选择车辆时&#xff0c;可关注传感器配置&#xff08;如是否标配毫米波雷达&#xff09;、功能覆盖场景&#xff08;如 AEB 是否支持夜间行人&#xff…

Prometheus+Grafana+K8s构建监控告警系统

一、技术介绍 Prometheus、Grafana及K8S服务发现详解 Prometheus简介 Prometheus是一个开源的监控系统和时间序列数据库&#xff0c;最初由SoundCloud开发&#xff0c;现已成为CNCF(云原生计算基金会)的毕业项目‌。它专注于实时监控和告警&#xff0c;特别适合云原生和分布式…

MATLAB脚本实现了一个三自由度的通用航空运载器(CAV-H)的轨迹仿真,主要用于模拟升力体在不同飞行阶段(初始滑翔段、滑翔段、下压段)的运动轨迹

%升力体:通用航空运载器CAV-H %读取数据1 升力系数 alpha = [10 15 20]; Ma = [3.5 5 8 10 15 20 23]; alpha1 = 10:0.1:20; Ma1 = 3.5:0.1:23; [Ma1, alpha1] = meshgrid(Ma1, alpha1); CL = readmatrix(simulation.xlsx, Sheet, Sheet1, Range, B2:H4); CL1 = interp2(…

Day09【基于jieba分词和RNN实现的简单中文分词】

基于jieba分词和RNN实现的中文分词 目标数据准备主程序预测效果 目标 本文基于给定的中文词表&#xff0c;将输入的文本基于jieba分词分割为若干个词&#xff0c;词的末尾对应的标签为1&#xff0c;中间部分对应的标签为0&#xff0c;同时将分词后的单词基于中文词表做初步序列…

Linux-服务器添加审计日志功能

#查看audit软件是否在运行(状态为active而且为绿色表示已经在运行) systemctl start auditd #如果没有在运行的话,查看是否被系统禁用 (audit为0表示被禁用) cat /proc/cmdline | grep -w "audit=0" #修改/etc/default/grub里面audit=0 改为audit=1 #更新GRUB…

uniappx项目上架各手机平台

前段时间用uniappx开发的App&#xff0c;领导要求要在各个主要手机平台上上架了&#xff0c;本来不是我的任务&#xff0c;后来其他人没有空交给我了&#xff0c;上架小白一枚&#xff0c;哭唧唧的自己研究吧&#xff0c;根据领导发的账号密码登录各个平台上架&#xff0c;花费…

第4次课 前缀和与差分 A

课堂学习 前缀和数组 前1个收购点&#xff1a;3箱 前2个收购点&#xff1a;325箱 前3个收购点&#xff1a;32510箱 以此类推… 数组a存储10个收购点的箱数。 收购点编号从1~10&#xff0c;数组下标也从1开始使用。 下标0位置直接赋值0 #include<bits/stdc.h> using nam…

MySQL部分总结

mysql学习笔记&#xff0c;如有不足还请指出&#xff0c;谢谢。 外连接&#xff0c;内连接&#xff0c;全连接 外连接&#xff1a;左外、右外 内连接&#xff1a;自己和自己连接 全连接&#xff1a;左外连接右外链接 mysql unique字段 unique可以在数据库层面避免插入相同…

Spring MVC 请求处理流程详解

步骤1&#xff1a;用户发起请求 所有请求首先被 DispatcherServlet&#xff08;前端控制器&#xff09;拦截&#xff0c;它是整个流程的入口。 DispatcherServlet 继承自 HttpServlet&#xff0c;通过 web.xml 或 WebApplicationInitializer 配置映射路径&#xff08;如 /&…

Vue 高级技巧深度解析

Vue 高级技巧深度解析 mindmaproot(Vue2高级技巧)组件通信EventBusprovide/inject$attrs/$listeners性能优化虚拟DOM优化函数式组件按需加载状态管理Vuex模块化持久化存储严格模式高级指令自定义指令动态组件异步组件渲染控制作用域插槽渲染函数JSX支持一、组件通信的进阶之道 …

2024年React最新高频面试题及核心考点解析,涵盖基础、进阶和新特性,助你高效备战

以下是2024年React最新高频面试题及核心考点解析&#xff0c;涵盖基础、进阶和新特性&#xff0c;助你高效备战&#xff1a; 一、基础篇 React虚拟DOM原理及Diff算法优化策略 • 必考点&#xff1a;虚拟DOM树对比&#xff08;同级比较、Key的作用、组件类型判断&#xff09; •…