当前位置: 首页 > article >正文

数据结构之LinkedList

系列文章目录

数据结构之ArrayList-CSDN博客


目录

系列文章目录

前言

一、模拟实现链表

1. 遍历链表

2. 插入节点

 3. 删除节点

4. 清空链表

二、链表的常见操作

1. 反转链表

2. 返回链表的中间节点

3. 链表倒数第 k 个节点

4. 合并两个有序链表

5. 分割链表

6. 判断链表是否回文

7. 找两个链表的第一个公共节点

8. 判断链表是否有环

9. 寻找链表入环的第一个节点

三、模拟实现双向链表

1. 遍历链表

2. 插入节点

3. 删除节点

4. 清空链表

四、ArrayList 和 LinkedList 的区别


前言

本文通过单链表的模拟实现,帮助了解单链表的底层原理,以及常见的链表的常用操作,比如反转链表,找链表的中间节点等。模拟实现双向链表,了解双向链表的底层原理,以及 ArrayList 和 LinkedList 的比较。


一、模拟实现链表

链表是物理存储结构上非连续,逻辑上连续的存储结构;每个节点都会保存下一个节点的哈希值,通过这个节点可以找到下一个节点;

链表的属性:用 head 表示链表的头节点;

public class MySingleList {static class ListNode{public int val;public ListNode next;public ListNode(int val){this.val = val;}}public ListNode head;// 链表的方法// ...
}

1. 遍历链表

以下方法都需要遍历一遍链表:

display(): void 打印节点信息;

size(): int 返回链表的长度;

contains(int key): boolean 判断链表中是否包含 key;

    // 打印所有节点信息public void display(){ListNode cur = head;while(cur != null){System.out.print(cur.val + " ");cur = cur.next;}}// 求链表的长度public int size(){ListNode cur = head;int count = 0;while(cur != null){count++;cur = cur.next;}return count;}// 查找关键字 key 是否在链表中public boolean contains(int key){ListNode cur = head;while(cur != null){if(cur.val == key){return true;}cur = cur.next;}return false;}

2. 插入节点

addFirst(int data): void 头插法,将节点插入到链表头节点的位置;

addLast(int data): void 尾插法,将节点插入到链表尾节点的位置,尾插的时候要注意,当链表没有节点,即 head == null,这时候要注意将要插入的节点设置为头节点;

findIndexPrev(int index): ListNode 找到 index 位置节点的前驱;

addIndex(int index, int data): void 在 index 位置插入节点;

插入之前需要先判断 index 位置是否合法;

如果合法再判断一下是否是头插,是否是尾插,因为这俩方法已经写好了,可以调用;

找到要插入节点的前驱,找到前驱之后进行插入;

    // 头插法public void addFirst(int data){ListNode node = new ListNode(data);node.next = head;head = node;}// 尾插法public void addLast(int data){ListNode node = new ListNode(data);ListNode cur = head;if(cur == null) {this.head = node;return;}while(cur.next != null){cur = cur.next;}cur.next = node;}// 在任意位置插入public void addIndex(int index, int data){if(index < 0 || index > size()){throw new PosOutOfBoundsException(index + "插入位置不合法");}if(index == 0){addFirst(data);return;}if(index == size()){addLast(data);return;}ListNode cur = findIndexPrev(index);ListNode node = new ListNode(data);node.next = cur.next;cur.next = node;}// 找到 index 下标的前一个节点private ListNode findIndexPrev(int index){ListNode cur = head;while(--index > 0){cur = cur.next;}return cur;}

 3. 删除节点

remove(int key): void 删除第一个值为 key  的节点;

如果链表为空则直接返回;

如果头节点为要删除的节点,直接删除;

如果要删除的节点不存在,抛异常;

如果要删除在后面,先找到要删除节点的前驱,再删除;

findPrev(int key): ListNode 找到值为 key 的节点的前驱,没有要删除的节点,返回 null;

removeAll(int key): void 删除所有值为 key 的节点;

如果链表为空,直接返回;

从头节点后面开始删除,找到要删除的节点和它的前驱,进行删除;

删除完成后,当前节点指针向后移动;

如果没有找到要删除的节点,前驱和当前节点指针都同步向后移动;

最后判断头节点,如果头节点也是要删除的节点,进行删除;

    // 删除节点public void remove(int key){if(head == null){return;}// 单独删除头节点if(head.val == key){head = head.next;return;}ListNode prev = findPrev(key);if(prev == null){throw new RuntimeException("要删除的节点不存在!");}ListNode del = prev.next;prev.next = del.next;}// 找到 data 节点的前驱private ListNode findPrev(int key){ListNode cur = head;while(cur.next != null){if(cur.next.val == key){return cur;}}return null;}// 删除所有值为 key 的节点public void removeAll(int key){if(head == null){return;}ListNode prev = head;ListNode cur = prev.next;while(cur != null){if(cur.val == key){prev.next = cur.next;cur = cur.next;}else{prev = cur;cur = cur.next;}}// 判断头结点if(head.val == key){head = head.next;}}

4. 清空链表

clear(): void 清空链表,只需要将头结点置空即可;

    // 清空链表public void clear(){this.head = null;}

二、链表的常见操作

1. 反转链表

reverseList(ListNode head): ListNode 反转链表;

如果链表为空,返回 null;

如果链表不为空,依次将 head 后面的元素进行头插;

    public ListNode reverseList(ListNode head) {if(head == null) return head;ListNode cur = head.next;head.next = null;while(cur != null){ListNode next = cur.next;cur.next = head;head = cur;cur = next;}return head;}

2. 返回链表的中间节点

middleNode(ListNode head): ListNode 返回链表的中间节点,如果链表是奇数个元素,返回中间节点,如果链表是偶数个元素,返回右中点节点;

定义快慢指针,快指针每次走两步,慢指针每次走一步,如果快指针走到最后一个位置或者空位置,返回慢指针指向的节点即可;

    public ListNode middleNode(ListNode head) {if(head == null){return head;}ListNode fast = head;ListNode slow = head;while(fast != null && fast.next != null){fast = fast.next;fast = fast.next;slow = slow.next;}return slow;}

3. 链表倒数第 k 个节点

findKthtoTail(ListNode head, int k): ListNode 找倒数第 k 个节点

先判断 head 是否为空,如果 head 为空,返回 null;

再判断 k 的值是否合法,如果不合法,返回 null;

定义快慢指针 fast 和 slow,先让 fast 走 k - 1步,再让 fast 和 slow 同时走, fast 走到尾巴节点的时候,slow 正好走到倒数第 k 个节点; 

    // 返回链表倒数第 k 个节点public ListNode findKthToTail(ListNode head, int k){if(head == null) return null;if(k <= 0 || k > size()) return null;ListNode fast = head;ListNode slow = head;while(--k > 0){fast = fast.next;}while(fast.next != null){fast = fast.next;slow = slow.next;}return slow;}

4. 合并两个有序链表

mergeTwoLists(ListNode list1, ListNode list2): ListNode 合并两个有序链表

两个链表的元素相互比较,小的加入新的队列,指针后移;

当有一个链表为空了,开始把剩下的链表的元素按顺序加入到新的链表中;

    public ListNode mergeTwoLists(ListNode list1, ListNode list2) {if(list1 == null) return list2;if(list2 == null) return list1;ListNode newHead = new ListNode();ListNode cur = newHead;while(list1 != null && list2 != null){if(list1.val <= list2.val){cur.next = list1;list1 = list1.next;}else{cur.next = list2;list2 = list2.next;}cur = cur.next;}while(list1 != null){cur.next = list1;list1 = list1.next;cur = cur.next;}while(list2 != null){cur.next = list2;list2 = list2.next;cur = cur.next;}return newHead.next;}

5. 分割链表

要求:将小于 x 的节点排在其余节点之前,不改变原来节点的顺序;

partition(ListNode pHead, int x): ListNode 分割链表;

小于 x 的节点放 head1 后面,大于等于 x 的节点放在 head2 后面;

合并 head1 和 head2,返回新的链表;

注意:后面的链表的尾巴节点的 next 一定要置空,避免成环;

    public ListNode partition(ListNode pHead, int x) {if(pHead == null) return null;ListNode head1 = new ListNode(0);ListNode head2 = new ListNode(0);ListNode cur1 = head1;ListNode cur2 = head2;ListNode cur = pHead;while(cur != null){if(cur.val < x){cur1.next = cur;cur1 = cur1.next;}else{cur2.next = cur;cur2 = cur2.next;}cur = cur.next;}// 这是需要注意的地方cur2.next = null;cur1.next = head2.next;return head1.next;}

6. 判断链表是否回文

chkPalindrom(ListNode A): boolean 检查链表是否回文;

reverse(ListNode head): ListNode 反转链表;

检查链表是否回文的关键首先是找到链表中点(奇数个节点找中点,偶数个节点找右中点),找到中点后从这个节点开始,逆置链表,形成两个链表;

分别从两个链表的头结点开始遍历链表,如果值不同,直接返回 false,如果值相同继续遍历,直到遍历完,返回 true;

    public boolean chkPalindrome(ListNode A) {if (A == null) return true;ListNode fast = A;ListNode slow = A;while (fast != null && fast.next != null) {fast = fast.next.next;slow = slow.next;}ListNode cur1 = A;ListNode cur2 = reverse(slow);boolean flag = true;while (cur1.next != null && cur2.next != null) {if (cur1.val != cur2.val) {flag = false;break;}cur1 = cur1.next;cur2 = cur2.next;}return flag;}public ListNode reverse(ListNode head) {ListNode newHead = new ListNode(0);ListNode cur = head;while (cur != null) {ListNode next = cur.next;cur.next = newHead.next;newHead.next = cur;cur = next;}return newHead.next;}

7. 找两个链表的第一个公共节点

getIntersectionNode(ListNode headA, ListNode headB): ListNode 找两个链表的第一个公共节点,没有公共节点返回 null;

定义两个指针遍历两个链表,同时让两个指针都往后走,如果相同返回节点即可;

如果不相同,当第一个指针遍历到最后,就让第一个指针指向第二个链表的头结点;同理,第二个指针边历到最后,让第二个指针也指向第一个链表;

这时候两个指针都同时向后移动,如果两个链表有公共节点,则一定会同时到达,因为两个指针速度相同,相同时间走的路程也一定相同;

如果两个链表没有公共节点,则最终会同时指向 null,返回 null 即可;

    public ListNode getIntersectionNode(ListNode headA, ListNode headB) {if(headA == null || headB == null) return null;ListNode cur1 = headA;ListNode cur2 = headB;while(cur1 != cur2){if(cur1 != null) cur1 = cur1.next;else cur1 = headB;if(cur2 != null) cur2 = cur2.next;else cur2 = headA;}return cur1;}

8. 判断链表是否有环

hasCycle(ListNode head): boolean 判断链表是否有环;

定义一个 fast,一个 slow 指针,每次 fast 走两步,slow 每次走一步,如果两个指针相遇了,就证明有环,否则就没有环;

    public boolean hasCycle(ListNode head) {ListNode fast = head;ListNode slow = head;while(fast != null && fast.next != null){fast = fast.next.next;slow = slow.next;if(fast == slow){return true;}}return false;}

9. 寻找链表入环的第一个节点

detectCycle(ListNode head): ListNode 寻找链表入环的第一个节点;

先找到 fast 和 slow 的相遇点,一个从起点出发,另一个从相遇点出发,最终两个指针会在环的入口点相遇;

    public ListNode detectCycle(ListNode head) {ListNode fast = head;ListNode slow = head;while(fast != null && fast.next != null){fast = fast.next.next;slow = slow.next;if(fast == slow){break;}}if(fast == null || fast.next == null) return null;slow = head;while(fast != slow){fast = fast.next;slow = slow.next;}return fast;}

三、模拟实现双向链表

双向链表的属性:用 head 表示链表的头节点,last 表示链表的尾巴节点;

public class MyLinkedList {static class ListNode{private int val;private ListNode prev;private ListNode next;public ListNode(int data){this.val = data;}}public ListNode head;public ListNode last;
}

1. 遍历链表

display(): void 打印链表;

size(): int 返回链表长度;

contains(int key): boolean 判断链表中是否包含 key;

    // 打印链表public void display(){ListNode cur = head;while(cur != null){System.out.print(cur.val + " ");cur = cur.next;}System.out.println();}// 返回链表长度public int size(){ListNode cur = head;int count = 0;while(cur != null){count++;cur = cur.next;}return count;}// 判断链表中是否包含 keypublic boolean contains(int key) {ListNode cur = head;while (cur != null) {if (cur.val == key) {return true;}cur = cur.next;}return false;}

2. 插入节点

addFirst(int data): void 头插法,将节点插入到链表头节点的位置;

注意:如果链表没有节点,插入的时候要把头指针和尾指针都指向插入的节点;

addLast(int data): void 尾插法,将节点插入到链表尾节点的位置,尾插的时候要

注意:如果链表没有节点,插入的时候要把头指针和尾指针都指向插入的节点;

findIndexPrev(int index): ListNode 找到 index 位置节点的前驱;

addIndex(int index, int data): void 在 index 位置插入节点;

插入之前需要先判断 index 位置是否合法;

如果合法再判断一下是否是头插,是否是尾插,因为这俩方法已经写好了,可以调用;

找到要插入节点的前驱和后继,进行插入;

    // 头插法public void addFirst(int data){ListNode node = new ListNode(data);if(head == null) {head = node;last = node;}else {node.next = head;head.prev = node;head = node;}}// 尾插法public void addLast(int data){ListNode node = new ListNode(data);if(head == null){head = node;last = node;}else{last.next = node;node.prev = last;last = node;}}// 在 index 位置插入public void addIndex(int index, int data){if(index < 0 || index > size()){throw new RuntimeException(index + "位置不合法!");}if(index == 0){addFirst(data);return;}else if(index == size()){addLast(data);return;}ListNode node = new ListNode(data);ListNode prevNode = findPrev(index);ListNode nextNode = prevNode.next;prevNode.next = node;node.prev = prevNode;node.next = nextNode;nextNode.prev = node;}private ListNode findPrev(int index){ListNode cur = head;while(--index > 0){cur = cur.next;}return cur;}

3. 删除节点

remove(int key): void 删除第一个值为 key  的节点;

找到要删除节点的前驱和后继;

如果前驱为空,就删除头节点,删除头结点要特殊处理只有一个节点的情况;

如果后继为空,就删除尾节点,删除尾节点要特殊处理只有一个节点的情况;

如果删除中间节点,删除后返回;

removeAll(int key): void 删除所有值为 key 的节点;

注意:原理同上,不同点是删除一个节点后,继续向后遍历;

    // 删除第一次出现关键字 key 的节点public void remove(int key){ListNode cur = head;while(cur != null){if(cur.val == key){ListNode prevNode = cur.prev;ListNode nextNode = cur.next;if(prevNode != null) {prevNode.next = nextNode;}else{head = head.next;if(head != null){head.prev = null;}}if(nextNode != null) {nextNode.prev = prevNode;}else{last = last.prev;if(last != null){last.next = null;}}break;}cur = cur.next;}}// 删除所有值为 key 的节点public void removeAll(int key){ListNode cur = head;while(cur != null) {if (cur.val == key) {ListNode prevNode = cur.prev;ListNode nextNode = cur.next;if (prevNode != null) {prevNode.next = nextNode;} else {head = head.next;if(head != null){head.prev = null;}}if (nextNode != null) {nextNode.prev = prevNode;} else {last = last.prev;if(last != null){last.next = null;}}cur = nextNode;}else{cur = cur.next;}}}

4. 清空链表

clear(): void 清空链表;

注意:要把 headlast 置空;

    public void clear(){ListNode cur = head;while(cur != null){ListNode next = cur.next;cur = null;cur = next;}head = null;last = null;}

四、ArrayList 和 LinkedList 的区别

存储上:

ArrayList 在存储空间上是连续的,LinkedList 逻辑上是,连续的,在存储空间上是不一定连续的;

操作上:

从查询元素上来说,ArrayList 的时间复杂度是 O(1),而 LinkedList 不支持随机访问;

从插入上来说:

LinkedList 的时间复杂度是 O(1),ArrayList 头插时间复杂度是 O(n),因为需要把把元素统一往后移一个位置;

ArrayList 在插入时,空间不够时,需要扩容,而 LInkedList 没有容量的概念;

应用场景:

ArrayList 适合频繁查询,LinkedList 适合频繁插入删除;

相关文章:

数据结构之LinkedList

系列文章目录 数据结构之ArrayList-CSDN博客 目录 系列文章目录 前言 一、模拟实现链表 1. 遍历链表 2. 插入节点 3. 删除节点 4. 清空链表 二、链表的常见操作 1. 反转链表 2. 返回链表的中间节点 3. 链表倒数第 k 个节点 4. 合并两个有序链表 5. 分割链表 6. 判…...

摆脱硬件依赖:SkyEye在轨道交通中的仿真应用

在城市轨道交通系统中&#xff0c;信号系统承担着确保列车安全、高效运行的关键任务。从排列进路、信号开放&#xff0c;到终点折返与接发车&#xff0c;几乎每一个调度动作背后都依赖于信号系统的精密控制与实时响应。作为信号系统的重要组成部分&#xff0c;目标控制器&#…...

使用变异系数增强 CFD 收敛标准

将描述性统计整合到 CFD 中&#xff0c;以评估可变性和收敛性。 挑战 在工程设计中&#xff0c;尤其是在进行仿真时&#xff0c;我们经常处理描述流体、温度、应力或浓度行为的大型数据集。以有意义的方式解释这些值需要的不仅仅是原始数字;它需要对统计的理解。 统计学在工程…...

解决获取视频第一帧黑屏问题

文章目录 解决获取视频第一帧黑屏问题核心代码 解决获取视频第一帧黑屏问题 废话不多说&#xff0c;直接上代码&#xff1a; <script setup> const status ref(请点击“添加视频”按钮添加视频) const videoElement ref(document.createElement(video)) const curren…...

物联网通信技术全景指南(2025)之如何挑选合适的物联网模块

物联网通信技术全景指南&#xff08;2025&#xff09;之 如何挑选合适的物联网模块 物联网通信技术全景指南&#xff08;2025&#xff09;一、技术代际演进与退网背景二、5G 物联网技术体系&#xff08;Sub-6 GHz 核心&#xff09;1. 技术分层架构2. 蜂窝技术性能矩阵3. Sub-6 …...

影楼精修-AI衣服祛褶皱算法解析

注&#xff1a;为避免侵权&#xff0c;本文所用图像均为AIGC生成或无版权网站提供&#xff1b; 衣服祛褶皱功能&#xff0c;目前在像素蛋糕、美图云修、百度网盘AI修图、阿里云都有相关的功能支持&#xff0c;它的价值就是将不平整的衣服图像&#xff0c;变得整齐平整&#xf…...

Day46 Python打卡训练营

知识点回顾&#xff1a; 1. 不同CNN层的特征图&#xff1a;不同通道的特征图 2. 什么是注意力&#xff1a;注意力家族&#xff0c;类似于动物园&#xff0c;都是不同的模块&#xff0c;好不好试了才知道。 3. 通道注意力&#xff1a;模型的定义和插入的位置 4. 通道注意力后…...

信号电压高,传输稳定性变强,但是传输速率下降?

信号电压高&#xff0c;传输稳定性变强&#xff0c;但是传输速率下降&#xff1f; 一、信号电压升高&#xff0c;传输稳定性变强 1.信号幅度更大&#xff0c;抗噪声能力增强 2.噪声&#xff0c;比如干扰电磁波&#xff0c;串扰等相对于信号幅度比例变小&#xff0c;误码率降低 …...

linux安全加固(非常详细)

安全加固方案原则 1.版本升级 对于系统和应用在使用过程中暴露的安全缺陷&#xff0c;系统或应用厂商会及时发布解决问题的升级补丁包。升级系统或应用版本&#xff0c;可有效解决旧版本存在的安全风险。2.关闭端口服务 在不影响业务系统正常运行情况下&#xff0c;停止或禁用承…...

关于事务的简介

一、引言​ 在数据处理与存储的领域中&#xff0c;事务&#xff08;Transaction&#xff09;是确保数据完整性和一致性的关键概念。无论是金融系统的资金转账、电商平台的订单处理&#xff0c;还是企业资源规划&#xff08;ERP&#xff09;系统的业务流程操作&#xff0c;事务都…...

qt控制台程序与qt窗口程序在读取数据库中文字段的差异!!巨坑

问题&#xff1a;最近在自己编写一个类&#xff0c;这个类需要对mysql数据库进行插入和查询。因为最后是以一个类文件的形式拿来单独使用&#xff0c;所以在创建项目的时候就创建了一个qt的控制台程序。但是在对数据库的内容进行查询时&#xff0c;出现了中文乱码。参考了之前的…...

动手学深度学习12.7. 参数服务器-笔记练习(PyTorch)

以下内容为结合李沐老师的课程和教材补充的学习笔记&#xff0c;以及对课后练习的一些思考&#xff0c;自留回顾&#xff0c;也供同学之人交流参考。 本节课程地址&#xff1a;35 分布式训练【动手学深度学习v2】_哔哩哔哩_bilibili 本节教材地址&#xff1a;12.7. 参数服务器…...

告别数据泥沼,拥抱智能中枢:King’s四位一体重塑科研生产力

在现代科研的战场上&#xff0c;数据堪称科研人员手中的“弹药”。然而&#xff0c;许多实验室却深陷数据管理的泥沼&#xff1a;硬盘里堆满了不同年份的实验记录&#xff0c;U盘里塞着各种格式的谱图&#xff0c;Excel表格里还留着手动计算的痕迹……&#xff0c;当科研人员想…...

智绅科技 —— 智慧养老 + 数字健康,构筑银发时代安全防护网

在老龄化率突破 21.3% 的当下&#xff0c;智绅科技以 "科技适老" 为核心理念&#xff0c;构建 "监测 - 预警 - 干预 - 照护" 的智慧养老闭环。 其自主研发的七彩喜智慧康养平台&#xff0c;通过物联网、AI 和边缘计算技术&#xff0c;实现对老年人健康与安…...

Code Composer Studio CCS 工程设置,如何设置h文件查找路径?

右键工程,选Properties,在Build>MSP430 Compiler>Optinizution Include Options 设置头文件的搜索路径。 比如我设置了这些: ${CCS_BASE_ROOT}/msp430/include ${PROJECT_ROOT} ${CG_TOOL_ROOT}/include "${workspace_loc:/${ProjName}/F5xx_F6xx_Core_Lib}&quo…...

Qt生成日志与以及捕获崩溃文件(mingw64位,winDbg)————附带详细解说

文章目录 Qt生成日志与以及报错文件(mingw64位&#xff0c;winDbg)0 背景与结果0.1 背景0.2 结果1 WinDbg1.1 安装1.2 使用 2 编写代码2.1 ccrashstack类2.2 编写输出捕获异常的dmp文件2.2 编写输出日志文件2.3 调用生成日志和dmp文件 参考 Qt生成日志与以及报错文件(mingw64位…...

web前端开发如何适配各分辨率

在开发Web应用时&#xff0c;适配不同的显示器分辨率是确保用户体验一致性的关键。以下是一些常见的显示器分辨率。 常见的显示器分辨率 PC屏幕分辨率 1366 x 768&#xff1a;普通液晶显示器 1920 x 1080&#xff1a;高清液晶显示器 2560 x 1440&#xff1a;2K高清显示器 4096…...

本机无法远程别的计算机的方法

在本地计算机上修改组策略 按下 Win R 组合键打开运行窗口&#xff0c;输入 gpedit.msc 并回车&#xff0c;打开组策略编辑器。依次展开路径&#xff1a;计算机配置 > 管理模板 > 系统 > 凭据分配。在右侧找到并双击 加密 Oracle 修正 策略。选择 已启用&#xff0c…...

智能手表健康监测系统的PSRAM存储芯片CSS6404LS-LI—高带宽、耐高温、微尺寸的三重突破

一、直击智能手表三大核心痛点 痛点场景风险传统方案缺陷连续生物数据流存储100Hz PPG信号产生82MB/s数据洪峰SPI NOR Flash带宽不足(≤50MB/s)高温环境稳定性腕表表面温度达50℃&#xff08;烈日/运动场景&#xff09;商用级存储器件(85℃)易触发数据错误极限空间约束PCB面积…...

蓝桥杯国赛题2022

首先这个题应该是一个01背包&#xff0c;背包容量为2022&#xff0c;有2022个物品&#xff0c;第i个物品的体积为i&#xff0c;只不过这里有两个限制条件&#xff0c;一个限制条件是和为2022&#xff0c;另一个限制条件为10个数&#xff0c;两个限制条件那就把加一维&#xff0…...

Pycharm中添加不了新建的Conda环境(此篇专门给Daidai写的)

安装好了Conda之后&#xff0c;在系统终端也创建好Conda环境&#xff0c;一切显示正常&#xff0c;但在Pycharm中添加不了新建的Conda环境&#xff0c;显示“Conda executable is not found” 解决“Conda executable is not found” conda环境新建如下 D:/Programs/anacond…...

如何选择专业数据可视化开发工具?为您拆解捷码全功能和落地指南!

分享大纲&#xff1a; 1、捷码核心功能&#xff1a;4维能力支撑大屏开发 2、3步上手&#xff1a;可视化大屏开发操作路径 3、适配场景&#xff1a;8大行业已验证方案 在各行各业要求数字化转型时代&#xff0c;数据可视化大屏已成为众多企业数据驱动的核心工具。面对市场上繁杂…...

关于如何使用VScode编译下载keil工程的步骤演示

1、vscode的插件市场下载keil Assistant 2 、点设置 3、复制keil的地址 4、粘贴到第…...

微信小程序动态效果实战指南:从悬浮云朵到丝滑列表加载

小红书爆款交互设计解析&#xff0c;附完整代码&#xff01; &#x1f525; 一、为什么动态效果是小程序的关键竞争力&#xff1f; 用户留存提升&#xff1a;数据显示&#xff0c;86.3%的微商从业者依赖微信小程序&#xff0c;而动态效果能显著降低跳出率。技术赋能体验&#…...

Redis底层数据结构之深入理解跳表(2)

上一篇文章中我们详细讲述了跳表的增添、查找和修改的操作&#xff0c;这篇文章我们来讲解一下跳表在多线程并发时的安全问题。在Redis中&#xff0c;除了网络IO部分和大文件的后台复制涉及到多线程外&#xff0c;其余任务执行时全部都是单线程&#xff0c;这也就意味着在Redis…...

大模型编程助手-Cline

官网&#xff1a; https://cline.bot/ Cline 是一款深度集成在 Visual Studio Code&#xff08;VSCode&#xff09; 中的开源 AI 编程助手插件&#xff0c;旨在通过结合大语言模型&#xff08;如 Claude 3.5 Sonnet、DeepSeek V3、Google Gemini 等&#xff09;和工具链&#…...

[蓝桥杯]兰顿蚂蚁

兰顿蚂蚁 题目描述 兰顿蚂蚁&#xff0c;是于 1986 年&#xff0c;由克里斯兰顿提出来的&#xff0c;属于细胞自动机的一种。 平面上的正方形格子被填上黑色或白色。在其中一格正方形内有一只"蚂蚁"。 蚂蚁的头部朝向为&#xff1a;上下左右其中一方。 蚂蚁的移…...

使用 Python 构建并调用 ComfyUI 图像生成 API:完整实战指南

快速打造你自己的本地 AI 图像生成服务&#xff0c;支持 Web 前端一键调用&#xff01; &#x1f4cc; 前言 在 AIGC 快速发展的今天&#xff0c;ComfyUI 作为一款模块化、节点式的图像生成界面&#xff0c;备受开发者青睐。但默认情况下&#xff0c;ComfyUI 主要通过界面交互…...

嵌入式学习笔记-freeRTOS taskENTER_CRITICAL(_FROM_ISR)跟taskEXIT_CRITICAL(_FROM_ISR)函数解析

一 函数taskENTER_CRITICAL&#xff0c;taskEXIT_CRITICAL 函数taskENTER_CRITICAL最终实现如下&#xff1a; 第①处按照系统设定的configMAX_SYSCALL_INTERRUPT_PRIORITY值对中断进行屏蔽 第②处调用一次自增一次 第③处检查中断状态寄存器位&#xff0c;如果有任何中断位置…...

Unity基础-数学向量

Unity基础-数学向量 二、向量相关用法 概述 向量在Unity游戏开发中扮演着重要角色&#xff0c;用于表示位置、方向、速度等。Unity提供了Vector2、Vector3等结构体来处理向量运算。 1. 向量基础操作 1.1 向量创建和访问 // 创建向量 Vector3 position new Vector3(1, 2,…...