数据结构*链表- LinkedList
什么是链表
相较于ArrayList顺序表来说,链表是物理存储结构上非连续存储结构(也就是地址不是连续的)。链表由一系列节点构成,每个节点包含数据和指向下一个节点的引用。链表的各个节点在内存里并非连续存储,而是通过引用相互连接。
节点就相当于下图所示:
value用来存储数据,next用来引用下一个节点。
链表的分类
一共分为三种:单向与双向、带头与不带头、循环与非循环
单向与双向
单向如下图所示:
双向如下图所示:
带头与不带头
带头如下图所示:
不带头如下图所示:
注意:
我在不带头的图中也标记了“head”,这里的意思是链表的第一个数据,这是会变化的(例如:当头插的时候,新增的节点就是“head”了)。而对于带头的来说,head是不会发生变化的,起到一个标记的作用。当头插的时候,只会插在head的后面。也就是说,head的数据是一个无效数据,没有意义。
循环与非循环
循环如下图所示:
非循环如下图所示:
重点学习
由于组合较多,我们主要学习的是单向、不带头、非循环链表和双向、不带头、非循环链表
自己简单实现一个单向、不带头、非循环链表
总的框架:
public interface IMySingleList {//头插法void addFirst(int data);//尾插法void addLast(int data);//插入到指定index下标位置,第一个数据节点为1号下标void addIndex(int index,int data);//查找是否包含关键字key是否在单链表当中boolean contains(int key);//删除第一次出现关键字为key的节点void remove(int key);//删除所有值为key的节点void removeAllKey(int key);//得到单链表的长度int size();//清空链表void clear();void display();
}
public class MySingleLinkedList implements IMySingleList{//利用静态内部类,定义节点static class ListNode {public int value;public ListNode next;public ListNode(int value) {this.value = value;}}//定义头节点public ListNode head;//主要是为了理解链表的形成public void creatList() {}@Overridepublic void addFirst(int data) {}@Overridepublic void addLast(int data) {}@Overridepublic void addIndex(int index, int data) {}@Overridepublic boolean contains(int key) {return false;}@Overridepublic void remove(int key) {}@Overridepublic void removeAllKey(int key) {}@Overridepublic int size() {return 0;}@Overridepublic void clear() {}@Overridepublic void display() {}
}
creatList()方法
代码展示:
public void creatList() {ListNode node1 = new ListNode(10);ListNode node2 = new ListNode(20);ListNode node3 = new ListNode(30);ListNode node4 = new ListNode(40);node1.next = node2;node2.next = node3;node3.next = node4;head = node1;
}
代码分析:
ListNode node1 = new ListNode(10);
ListNode node2 = new ListNode(20);
ListNode node3 = new ListNode(30);
ListNode node4 = new ListNode(40);
上述代码是用来创建节点的。
node1.next = node2;
node2.next = node3;
node3.next = node4;
上述代码是用来进行链接的,将一个节点指向另一个节点的引用。
head = node1;
上述代码是将head头节点定义为node1。因为当方法执行完毕,临时变量会被回收,这时候是找不到node1等的其他变量,这时候通过head来找到链表。
通过调试来观察。
display()方法
代码展示:
public void display() {ListNode cur = head;while(cur != null) {System.out.print(cur.value +" ");cur = cur.next;}System.out.println();
}
代码分析:
ListNode cur = head;
上述代码是为了使head保持不变,方法结束后仍能通过head找到链表。
while(cur != null) {System.out.print(cur.value +" ");cur = cur.next;//将cur指向下一个节点
}
上述代码通过while循环实现了value的打印。注意:循环条件一定是cur != null
,而不是cur.next != null
!!!
总结:while循环条件如果是cur != null
,就会遍历所有的节点,cur此时为null;如果条件是cur.next != null
,此时最后一个节点不会被遍历,cur.next此时为null。
size()方法
代码展示:
public int size() {int usedSize = 0;ListNode cur = head;while(cur != null) {cur = cur.next;usedSize++;}return usedSize;
}
代码分析:
由于要遍历所有的节点,所以while条件是cur != null
。
contains(int key)方法
代码展示:
public boolean contains(int key) {ListNode cur = head;while(cur != null) {if(cur.value == key) {return true;}cur = cur.next;}return false;
}
代码分析:
由于要遍历所有的节点,所以while条件是cur != null
。
addFirst(int data)方法
代码展示:
public void addFirst(int data) {ListNode node = new ListNode(data);node.next = head;head = node;
}
代码分析:
当链表中没有节点时,也是成立的。head为null,node.next也为null。
addLast(int data)方法
代码展示:
public void addLast(int data) {ListNode cur = head;if(head == null) {addFirst(data);return;}ListNode node = new ListNode(data);while (cur.next != null) {cur = cur.next;}cur.next = node;
}
代码分析:
为了使cur指向最后一个节点(cur不为null),while循环条件就要为cur.next != null
。
当链表为空时,cur.next为空(会出现空指针异常),此时相当于头插,可以直接调用addLast(int data)方法。
addIndex(int index, int data)方法
代码展示:
public void addIndex(int index, int data) {//1、判断当index为1时,即要进行头插if(index == 1) {addFirst(data);return;}//2、判断当index为有效数据+1时,即要进行尾插if(index == size() + 1) {addLast(data);return;}//3、检查index下标合法性checkIndex(index);//4、进行中间节点的插入ListNode node = new ListNode(data);ListNode cur = findIndex(index);node.next = cur.next;cur.next = node;
}
//找到index下标节点的前一个节点
private ListNode findIndex(int index) {ListNode cur = head;int count = index - 2;while (count != 0) {cur = cur.next;count--;}return cur;
}
private void checkIndex(int index) {if(index <= 0 || index > size()) {throw new IndexException("下标位置不合法!");}
}
//自定义异常
public class IndexException extends RuntimeException{public IndexException() {super();}public IndexException(String message) {super(message);}
}
代码分析:
还需要考虑是否为头插、尾插;是否index不合法
remove(int key)方法
代码展示:
public void remove(int key) {//当链表为空时,即无法删除if(head == null) {System.out.println("链表为空,无法删除!");return;}//当链表第一个为要删除的数据,只需要移动head指向if(head.value == key) {head = head.next;return;}//定义要删除节点的前一个节点ListNode cur = search(key);//当没有找到要删除的数据(cur也就是null),直接返回if(cur == null) {System.out.println("链表中没有你要找的数据!");return;}ListNode delete = cur.next;cur.next = delete.next;}
private ListNode search(int key) {ListNode cur = head;while(cur.next != null) {if(cur.next.value == key) {return cur;}cur = cur.next;}//没有找到返回nullreturn null;
}
代码分析:
删除思路如下:
对于找到要删除的节点前一个节点,可以定义一个方法来查找,如下:
removeAllKey(int key)方法
代码展示:
public void removeAllKey(int key) {//当链表为空时,即无法删除if(head == null) {System.out.println("链表为空,无法删除!");return;}ListNode prev = head;ListNode cur = prev.next;while (cur != null) {if(cur.value == key) {prev.next = cur.next;cur = cur.next;}else {prev = prev.next;cur = cur.next;}}//判断头节点if(head.value == key) {head = head.next;}
}
代码分析:
clear()方法
代码展示:
public void clear() {ListNode cur = head;ListNode curN = head;while (cur != null) {cur.value = 0;curN = cur.next;cur.next = null;cur = curN;}//this.head = null;
}
代码分析:
可以直接将头节点置为null,此时后面不再被引用,被回收了;
也可以手动将所有节点置为null。
扩展链表方法
反转链表
要求改变链表结构(达到下图效果),时间复杂度为O(N)。
代码展示:
public void reverseList(ListNode head) {//当链表没有节点,返回if(head == null) {return;}//链表只有一个节点,返回if(head.next == null) {return;}ListNode cur = head.next;head.next = null;while (cur != null) {ListNode curN = cur.next;cur.next = head;head = cur;cur = curN;}
}
代码分析:
只需要将head后面的节点依次头插到head前面,就完成了逆序。
1、
2、
返回链表中间节点。
如果有两个中间节点,则返回第二个节点。
代码展示:
方法一:调用size()方法,返回第size()/2个节点
public ListNode middleNode(ListNode head) {int count = size()/2;ListNode cur = head;while (count != 0) {cur = cur.next;count--;}return cur;
}
方法二:使用快慢指针,让fast走两步,slow走一步,当fast走完了,slow刚好走到中间。
public ListNode middleNode() {ListNode fast = head;ListNode slow = head;while (fast != null && fast.next != null) {//while (fast.next != null && fast != null) { 错误fast = fast.next.next;slow = slow.next;}return slow;
}
代码分析:
方法二:
对于方法一以来说,循环了两次,而方法二只循环了一次。
输出倒数第k个节点
代码展示:
方法一:调用size()方法,返回第size() - k + 1个节点
public int kthToLast(ListNode head, int k) {if(k<0 || k > size()) {System.out.println("k值不合法");return -1;}ListNode cur = head;int count = size() -k;while ( count > 0) {cur = cur.next;count--;}return cur.value;
}
方法二:使用快慢指针,让fast先走k - 1步
public int kthToLast(ListNode head, int k) {if(k<0 || head == null) {System.out.println("k值不合法");return -1;}ListNode fast = head;ListNode slow = head;int count = k - 1;while(count > 0) {fast = fast.next;if(fast == null) {return -1;}count--;}while (fast.next != null) {fast = fast.next;slow = slow.next;}return slow.value;
}
代码分析:
方法二只遍历了一遍链表
合并两个升序链表
代码展示:
public ListNode mergeTwoLists(ListNode headA, ListNode headB) {ListNode headNew = new ListNode(-1);ListNode temp = headNew;while (headA != null && headB != null) {//当有一个链表没有节点了,此时就结束循环了if (headA.val >= headB.val) {temp.next = headB;temp = headB;headB = headB.next;} else {temp.next = headA;temp = headA;headA = headA.next;}}if (headB == null) {//对于headA还有节点temp.next = headA;}if (headA == null) {//对于headB还有节点temp.next = headB;}return headNew.next;//headNew并不是原链表中的节点,返回后面的即可}
代码分析:
链表回文结构判断
代码展示:
public boolean chkPalindrome(ListNode head) {if (head == null) {return true;}//找到中间节点ListNode slow = head;ListNode fast = head;while(fast != null && fast.next != null) {fast = fast.next.next;slow = slow.next;}//翻转后半部分链表ListNode cur = slow.next;slow.next = null;while (cur != null) {ListNode curN = cur.next;cur.next = slow;slow = cur;cur = curN;}//让head走到slow,进行比较while (head != slow) {//先进行值的判断if(head.value != slow.value) {return false;}//用于判断偶数情况if(head.next == slow) {return true;}head =head.next;slow = slow.next;}return true;
}
代码分析:
链表分割
给定x,将所有小于x的节点排在其余节点之前,且不能改变原来的数据顺序。
代码展示:
public ListNode partition(ListNode head,int x) {ListNode bStart = null;ListNode bEnd = null;ListNode aStart = null;ListNode aEnd = null;ListNode cur = head;while (cur != null) {if (cur.value < x) {if (bStart == null) {bStart = cur;bEnd = cur;} else {bEnd.next = cur;bEnd = bEnd.next;}} else {if (aStart == null) {aStart = cur;aEnd = cur;}else {aEnd.next = cur;aEnd = aEnd.next;}}cur = cur.next;}//当没有小于x的值时,第一个链表为空if(bStart == null) {return aStart;}//大于等于x的值中最后的节点不一定指向null,可能还指向原链表中的节点,此时需要置为nullif(aEnd != null) {aEnd.next = null;}bEnd.next = aStart;return bStart;
}
代码分析:
找到两个链表公共节点
代码展示:
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {int lenA = 0;int lenB = 0;ListNode pA = headA;ListNode pB = headB;//计算lenA的值while (pA != null) {lenA++;pA = pA.next;}//计算lenB的值while (pB != null) {lenB++;pB = pB.next;}int len = lenA - lenB;//再次需要遍历链表pA = headA;pB = headB;//这个判断是让pA始终为较长的链表if(len < 0) {pA = headB;pB = headA;len = lenB - lenA;}//让长的pA指向的链表移动len步while (len != 0) {pA = pA.next;len--;}//让两个同时走,当节点相同时,循环结束while (pA != pB) {pA = pA.next;pB = pB.next;}return pA;
}
代码分析:
判断是否为环形链表
代码展示:
public boolean hasCycle(ListNode head) {ListNode slow = head;ListNode fast = head;while (fast != null && fast.next != null) {fast = fast.next.next;slow = slow.next;if(fast == slow) {return true;}}return false;
}
代码分析:
让fast始终比slow快走一步,这样肯定会在环中的某一处相遇。当fast走不了一步或者两步时,链表就没有构成环。
自己简单实现一个双向、不带头、非循环链表
代码展示:
public class MyLinkedList implements IMyLinkedList{static class ListNode{public int value;public ListNode next;public ListNode prev;public ListNode(int value) {this.value = value;}}public ListNode head;public ListNode Last;@Overridepublic 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;}}@Overridepublic 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;}}@Overridepublic void addIndex(int index, int data) {//判断index合法性checkIndex(index);//处理特殊位置if(index == 0) {addFirst(data);return;}if(index == size() - 1) {addLast(data);return;}ListNode cur = search(index);ListNode node = new ListNode(data);//先链接正方向node.next = cur;cur.prev.next = node;//再链接反方向node.prev = cur.prev;cur.prev = node;}private ListNode search(int index) {ListNode cur = head;while (index > 0) {cur = cur.next;index--;}return cur;}private void checkIndex(int index) {if(index < 0 || index >= size()) {throw new IndexException("index下标不合法");}}@Overridepublic boolean contains(int key) {ListNode cur = head;while (cur != null) {if(cur.value == key) {return true;}cur = cur.next;}return false;}@Overridepublic void remove(int key) {if(head == null){System.out.println("没有数据,无法删除");}ListNode cur = head;while (cur != null) {if(cur.value == key) {//开始删除//1、删除的是头节点if(cur == head) {head = head.next;//下面判断是为了防止链表只有一个节点,访问head.prev会空指针异常if(head != null) {head.prev = null;}}else {//2、当删除的是尾节点if(cur.next == null){cur.prev.next = null;Last = Last.prev;}else {//3、删除的是中间节点cur.prev.next = cur.next;cur.next.prev = cur.prev;}}return;}cur = cur.next;}}@Overridepublic void removeAllKey(int key) {if(head == null){System.out.println("没有数据,无法删除");}ListNode cur = head;while (cur != null) {if(cur.value == key) {//开始删除//1、删除的是头节点if(cur == head) {head = head.next;//下面判断是为了防止链表只有一个节点,访问head.prev会空指针异常if(head != null) {head.prev = null;}}else {//2、当删除的是尾节点if(cur.next == null){cur.prev.next = null;Last = Last.prev;}else {//3、删除的是中间节点cur.prev.next = cur.next;cur.next.prev = cur.prev;}}//return;不返回,继续开始遍历删除key值}cur = cur.next;}}@Overridepublic int size() {ListNode cur = head;int count = 0;while (cur != null) {count++;cur = cur.next;}return count;}@Overridepublic void clear() {ListNode cur = head;while(cur != null) {ListNode curN = cur.next;cur.next = null;cur.prev = null;cur = curN;}head = null;Last = null;}@Overridepublic void display() {ListNode cur = head;while (cur != null) {System.out.print(cur.value+" ");cur = cur.next;}System.out.println();}public void redisplay() {ListNode cur = Last;while (cur != null) {System.out.print(cur.value+" ");cur = cur.prev;}System.out.println();}
}
官方提供的链表(双向链表)
构造方法
方法 | 功能 |
---|---|
LinkedList() | 无参构造 |
public LinkedList(Collection<? extends E> c) | 使用其他集合容器中的元素构造List |
public static void test1() {LinkedList<Integer> list = new LinkedList<>();list.add(1);list.add(2);list.addLast(10);list.addFirst(3);list.add(4);System.out.println(list);System.out.println("-------------");List<Integer> list1 = new LinkedList<>();list1.add(1);list1.add(12);list1.add(13);list1.add(14);list1.add(15);System.out.println(list1);System.out.println("-------------");List<Number> list2 = new LinkedList<>(list1);System.out.println(list2);
}
常用方法
方法 | 功能 |
---|---|
boolean add(E e) | 尾插e |
void add(int index,E element) | 将e插入到index位置 |
boolean addAll(Collection<? extends E> c) | 尾插c中的元素 |
E remove(int index) | 删除index位置元素 |
boolean remove(Object o) | 删除遇到的第一个o |
E get(int index) | 获取下标index位置元素 |
E set(int index,E element) | 将下标index位置元素设置为element(替换) |
void clear() | 清空 |
boolean contains(Object o) | 判断o是否在线性表中 |
int indexOf(Object o) | 返回第一个o所在下标 |
int lastindexOf(Object o) | 返回最后一个o所在下标 |
List<E> subList(int fromIndex,int toIndex) | 截取部分list |
这些常用方法和ArrayList是一样的,但具体的底层实现过程是完全不一样的。
遍历链表
其中的方法和遍历ArrayList是一样的
public static void test2() {LinkedList<Integer> list = new LinkedList<>();list.add(1);list.add(2);list.add(3);list.add(4);list.add(5);list.add(6);System.out.println("--------直接sout输出--------");System.out.println(list);System.out.println("--------for循环遍历--------");for (int i = 0; i < list.size(); i++) {System.out.print(list.get(i)+" ");}System.out.println();System.out.println("--------foreach循环遍历--------");for (Integer integer : list) {System.out.print(integer + " ");}System.out.println();System.out.println("--------迭代器正序输出1--------");Iterator<Integer> it = list.listIterator();while (it.hasNext()) {System.out.print(it.next()+" ");}System.out.println();System.out.println("--------迭代器正序输出2--------");ListIterator<Integer> its = list.listIterator();while (its.hasNext()) {System.out.print(its.next()+" ");}System.out.println();System.out.println("--------迭代器正序输出3(从指定下标位置输出)--------");ListIterator<Integer> itss = list.listIterator(2);while (itss.hasNext()) {System.out.print(itss.next()+" ");}System.out.println();System.out.println("--------迭代器逆序输出--------");ListIterator<Integer> reits = list.listIterator(list.size());while (reits.hasPrevious()) {System.out.print(reits.previous()+" ");}
}
链表优缺点
优点
1、插入与删除高效,时间复杂度为O(1)。
2、由于链表的节点在内存中可以是不连续存储的,适合存储分散的数据。
缺点:
1、随机访问效率低,需要通过循环来遍历节点,时间复杂度为O(n)。
相关文章:
数据结构*链表- LinkedList
什么是链表 相较于ArrayList顺序表来说,链表是物理存储结构上非连续存储结构(也就是地址不是连续的)。链表由一系列节点构成,每个节点包含数据和指向下一个节点的引用。链表的各个节点在内存里并非连续存储,而是通过引…...
WebRTC服务器Coturn服务器用户管理和安全性
1、概述 Coturn服务器对用户管理和安全方面也做了很多的措施,以下会介绍到用户方面的设置 1.1、相关术语 1.1.1 realm 在 coturn 服务器中,域(realm)是一种逻辑上的分组概念,用于对不同的用户群体、应用或者服务进行区…...
MySQL聚簇索引和非聚簇索引
聚簇索引(Clustered Index)和非聚簇索引(Non-Clustered Index)是数据库中常用的两种索引类型,它们在数据存储和检索方式上有显著的区别。 一、聚簇索引(Clustered Index) 聚簇索引是数据表中的…...
QT加入阿里云OSS上传图片SDK,编译报错:error LNK2019: 无法解析的外部符号 EVP_MD_CTX_init
参考此链接把OSS上传图片的SDK,cmake成lib库,如下图 将lib库放入自己的项目文件夹下,并在pro文件中添加此lib库。而解决 “无法解析的外部符号 EVP_MD_CTX_init” 问题,则需要将third_party文件夹下的一些依赖库和头文件都放到自己…...
正点原子TFTLCD扩展
声明:该文章代码是在正点原子教学下写出的LCD驱动代码上进行了修改能兼容更多字号( ˘ ˘)❤️ 如有侵权,请私信联系删除 文章目录 前言代码lcd.clcd.hfont.h 前言 由于TFTLCD4.3寸屏幕太大了,正点原子的代码只能显示12/16/24字号的字符或者…...
部署Megatron - LM,快速上手使用
安装Megatron - LM 首先检查一下当前环境是否已经有 NVIDIA 驱动和 CUDA: nvidia-smi 直接在当前环境安装运行 PyTorch 和 Megatron-LM不使用 Docker 之前我们看到目前的环境有 NVIDIA V100 GPU 和 CUDA 12.1,我们可以安装对应的 GPU 版本 PyTorch。…...
赛灵思 XC7K325T-2FFG900I FPGA Xilinx Kintex‑7
XC7K325T-2FFG900I 是 Xilinx Kintex‑7 系列中一款工业级 (I) 高性能 FPGA,基于 28 nm HKMG HPL 工艺制程,核心电压标称 1.0 V,I/O 电压可在 0.97 V–1.03 V 之间灵活配置,并可在 –40 C 至 100 C 温度范围内稳定运行。该器件提供…...
20.1Linux的PWM驱动实验(知识点)_csdn
PWM 是很常用到功能,我们可以通过 PWM 来控制电机速度,也可以使用 PWM 来控制LCD 的背光亮度。本章我们就来学习一下如何在 Linux 下进行 PWM 驱动开发。 在之前学过STM32的就知道这部分内容,利用占空比来调节电机的转速。 1、PWM 驱动简析 …...
如何在 Java 中从 PDF 文件中删除页面(教程)
由于 PDF 文件格式不是 Java 原生支持的,因此要从 PDF 中删除页面,你需要使用外部库。 本教程介绍如何使用 JPedal 来实现这一功能。 开始使用 • 将 JPedal 添加到你的类路径或模块路径中(可从官网下载安装试用版 JAR 文件) •…...
2026《数据结构》考研复习笔记五(栈、队列)
栈、队列 一、栈1.卡特兰数2.不合法的出栈序列 二、队列1.循环队列2.输入输出受限队列(四个数1234) 三、算法1.栈在括号匹配中的应用2.中缀表达式求值(通过转化为后缀表达式再后缀表达式求值)3.中缀表达式转化为后缀表达式4.后缀表…...
本地部署DeepSeek大模型
本地部署 ollama 下载Ollama ollama支持的模型:Ollama Search 直接下载,发现默认是下载C盘,并且不能选择安装目录,这对我C盘的压力太大了。 查阅资料:发现可以修改 参考将Ollama安装到非C盘路径_ollama不安装在c盘…...
C++ / 引用 | 类
引用本 作用: 给变量起别名 语法: 数据类型 & 别名 原名; 应用代码 #include <iostream>using namespace std;int main() {int a 10;int& b a;b 100;cout << "a " << a << endl;cout <…...
在任意路径下简单开启jupyter notebook
正常的开启方式为: 安装anaconda, 在anaconda界面开启jupyter. 但是启动后root的路径不好改变。 可以直接通过cmd方式打开jupyter. cd D: # cd到d盘 jupyter notebook # 启动此时开启jupyter notebook, root为D盘路径。 按此方式可以在任意路径启动jupyter noteb…...
2025年阿里云云计算ACP高级工程师认证模拟试题(附答案解析)
这篇文章的内容是阿里云云计算ACP高级工程师认证考试的模拟试题。 所有模拟试题由AI自动生成,主要为了练习和巩固知识,并非所谓的 “题库”,考试中如果出现同样试题那真是纯属巧合。 1、设计云上架构时,如果能充分了解云服务的特…...
锂电池4.2V升压24V推荐哪些升压芯片?高效率国产SL4013输入耐压2.7V-25V
SL4013作为一款高性能升压型DC-DC转换芯片,在单节锂电池(4.2V)升压至24V的应用中展现出以下核心优势: 一、宽输入电压适应性 SL4013支持2.7V-25V的输入范围,尤其适合单节锂电池(3.7V-4.2V)的宽…...
中电金信联合阿里云推出智能陪练Agent
在金融业加速数智化转型的今天,提升服务效率与改善用户体验已成为行业升级的核心方向。面对这一趋势,智能体与智能陪练的结合应用,正帮助金融机构突破传统业务模式,开拓更具竞争力的创新机遇。 在近日召开的阿里云AI势能大会期间&…...
基于扣子(Coze.cn)与火山引擎构建高性能智能体的实践指南
1. 引言 1.1. 背景与目标 人工智能(AI)智能体(Agent)平台的兴起,例如扣子(Coze),正显著改变我们构建复杂 AI 应用的方式 1。这些平台旨在降低技术门槛,让不同技能水平的…...
w~视觉~3D~合集2
我自己的原文哦~ https://blog.51cto.com/whaosoft/13766161 #Sin3DGen 最近有点忙 可能给忘了,贴了我只是搬运工 发这些给自己看, 还有下面不是隐藏是发布出去 ~ 北京大学xxx团队联合山东大学和xxx AI Lab的研究人员,提出了首个基于单样例场景无需训练便可生…...
SAS宏核心知识与实战应用
1. SAS宏基础 1.1 核心概念 1.1.1 宏处理器 宏处理器在SAS程序运行前执行,用于生成动态代码,可实现代码的灵活定制。 通过宏处理器,可基于输入参数动态生成不同的SAS代码,提高代码复用性。 1.1.2 宏变量 宏变量是存储文本值的容器,用&符号引用,如&var,用于存储…...
windows使用openssl生成IIS自签证书全流程
使用 OpenSSL 生成适用于 IIS 的证书,通常需要经过以下步骤:生成私钥、生成证书签名请求(CSR)、生成自签名证书或通过 CA 签名,最后将证书转换为 IIS 所需的 PFX 格式。以下是详细步骤: 1. 安装 OpenSSL …...
笔记本电脑研发笔记:BIOS,Driver,Preloader详记
在笔记本电脑的研发过程中,Driver(驱动程序)、BIOS(基本输入输出系统)和 Preloader(预加载程序)之间存在着密切的相互关系和影响,具体如下: 相互关系 BIOS 与 Preload…...
鸿蒙生态:鸿蒙生态校园行心得
(个人观点,仅供参考) 兄弟们,今天来浅浅聊一聊这次的设立在长沙的鸿蒙生态行活动。 老样子,我们先来了解一下这个活动: Harmon&#x…...
云原生周刊:KubeSphere 平滑升级
开源项目推荐 Kagent Kagent 是一个开源的 K8s 原生框架,旨在帮助 DevOps 和平台工程师在 K8s 环境中构建和运行 AI 代理(Agentic AI)。与传统的生成式 AI 工具不同,Kagent 强调自主推理和多步骤任务的自动化执行,适…...
Uniapp:swiper(滑块视图容器)
目录 一、基本概述二、属性说明三、基本使用 一、基本概述 一般用于左右滑动或上下滑动,比如banner轮播图 二、属性说明 属性名类型默认值说明平台差异说明indicator-dotsBooleanfalse是否显示面板指示点indicator-colorColorrgba(0, 0, 0, .3)指示点颜色indicat…...
开源的自动驾驶模拟器
以下是目前主流的 开源自动驾驶模拟器,适用于算法开发、测试和研究: 1. CARLA 官网/GitHub: carla.org | GitHub许可证: MIT特点: 基于虚幻引擎(Unreal Engine),提供高保真城市场景(支…...
Uniapp:scroll-view(区域滑动视图)
目录 一、基本概述二、属性说明三、基本使用3.1 纵向滚动3.2 横向滚动 一、基本概述 scroll-view,可滚动视图区域。用于区域滚动。 二、属性说明 属性名类型默认值说明平台差异说明scroll-xBooleanfalse允许横向滚动scroll-yBooleanfalse允许纵向滚动 三、基本使…...
【漏洞复现】Struts2系列
【漏洞复现】Struts2系列 1. 了解Struts21. Struts2 S2-061 RCE (CVE-2020-17530)1. 漏洞描述2. 影响版本3. 复现过程 1. 了解Struts2 Apache Struts2是一个基于MVC设计模式的Web应用框架,会对某些标签属性(比如 id)的…...
洗车小程序系统前端uniapp 后台thinkphp
洗车小程序系统 前端uniapp 后台thinkphp 支持多门店 分销 在线预约 套餐卡等...
【RuleUtil】适用于全业务场景的规则匹配快速开发工具
一、RuleUtil 开发背景 1.1 越来越多,越来越复杂的业务规则 1、规则的应用场景多 2、规则配置的参数类型多(ID、数值、文本、日期等等) 3、规则的参数条件多(大于、小于、等于、包含、不包含、区间等等) 4、规则的结…...
多表查询之嵌套查询
目录 引言 一、标量嵌套查询 二、列嵌套查询 三、行嵌套查询 四、表嵌套查询 引言 1、概念 SQL语句中嵌套 select 语句,称为嵌套查询,又称子查询。嵌套查询外部的语句可以是 insert / update / delete / select 的任何一个。 嵌套…...
js原型链prototype解释
function Person(){} var personnew Person() console.log(啊啊,Person instanceof Function);//true console.log(,Person.__proto__Function.prototype);//true console.log(,Person.prototype.__proto__ Object.prototype);//true console.log(,Function.prototype.__prot…...
RK3588 ubuntu20禁用自带的TF卡挂载,并设置udev自动挂载
禁用系统的自动挂载(udisks2) sudo vim /etc/udev/rules.d/80-disable-automount.rules添加 ACTION"add", KERNEL"mmcblk1p1", ENV{UDISKS_IGNORE}"1"KERNEL“mmcblk1p1”:匹配设备名(TF卡通常是…...
【Pytorch 中的扩散模型】去噪扩散概率模型(DDPM)的实现
介绍 广义上讲,扩散模型是一种生成式深度学习模型,它通过学习到的去噪过程来创建数据。扩散模型有很多变体,其中最流行的通常是文本条件模型,它可以根据提示生成特定的图像。一些扩散模型(例如 Control-Net࿰…...
AR/VR衍射光波导性能提升遇阻?OAS光学软件有方法
衍射波导准直系统设计案例 简介 在现代光学显示技术中,衍射光波导系统因其独特的光学性能和紧凑的结构设计,在增强现实(AR)、虚拟现实(VR)等领域展现出巨大的应用潜力。本案例聚焦于衍射波导准直系统&…...
联易融受邀参加上海审计局金融审计处专题交流座谈
近日,联易融科技集团受邀出席了由上海市审计局金融审计处组织的专题交流座谈,凭借其在供应链金融领域的深厚积累和创新实践,联易融为与会人员带来了精彩的分享,进一步加深现场对供应链金融等金融发展前沿领域的理解。 在交流座谈…...
【中级软件设计师】程序设计语言基础成分
【中级软件设计师】程序设计语言基础成分 目录 【中级软件设计师】程序设计语言基础成分一、历年真题二、考点:程序设计语言基础成分1、基本成分2、数据成分3、控制成分 三、真题的答案与解析答案解析 复习技巧: 若已掌握【程序设计语言基础成分】相关知…...
高并发抢券系统设计与落地实现详解
📚 目录 一、业务背景与系统目标 二、架构设计总览 三、热点数据预热与缓存设计 四、抢券逻辑核心 —— Redis Lua 脚本 五、抢券接口实现要点 六、结果同步机制设计 七、性能优化策略 八、总结 在电商系统中,抢券作为一种典型的秒杀业务场景&a…...
外商在国内宣传 活动|发布会|参展 邀请媒体
传媒如春雨,润物细无声,大家好,我是51媒体胡老师。 外商在国内开展宣传活动、发布会或参展时,邀请媒体是扩大影响力、提升品牌知名度的关键环节。 一、活动筹备阶段:选择具有实力且更有性价比的媒体服务商(…...
物联网 (IoT) 安全简介
什么是物联网安全? 物联网安全是网络安全的一个分支领域,专注于保护、监控和修复与物联网(IoT)相关的威胁。物联网是指由配备传感器、软件或其他技术的互联设备组成的网络,这些设备能够通过互联网收集、存储和共享数据…...
大模型面经 | 春招、秋招算法面试常考八股文附答案(四)
大家好,我是皮先生!! 今天给大家分享一些关于大模型面试常见的面试题,希望对大家的面试有所帮助。 往期回顾: 大模型面经 | 春招、秋招算法面试常考八股文附答案(RAG专题一) 大模型面经 | 春招、秋招算法面试常考八股文附答案(RAG专题二) 大模型面经 | 春招、秋招算法…...
从零开始学习MySQL的系统学习大纲
文章目录 前言第一阶段:数据库与 MySQL 基础认知数据库基础概念MySQL 简介 第二阶段:MySQL 安装与环境搭建安装前的准备MySQL 安装过程安装后的配置 第三阶段:SQL 基础语法SQL 概述数据库操作数据表操作数据操作 第四阶段:SQL 高级…...
ycsb性能测试的优缺点
YCSB(Yahoo Cloud Serving Benchmark)是一个开源的性能测试框架,用于评估分布式系统的读写性能。它具有以下优点和缺点: 优点: 简单易用:YCSB提供了简单的API和配置文件,使得性能测试非常容易…...
Linux:简单自定义shell
1.实现原理 考虑下⾯这个与shell典型的互动: [rootlocalhost epoll]# ls client.cpp readme.md server.cpp utility.h [rootlocalhost epoll]# ps PID TTY TIME CMD 3451 pts/0 00:00:00 bash 3514 pts/0 00:00:00 ps ⽤下图的时间轴来表⽰事件的发⽣次序。其中时…...
Android Studio开发 SharedPreferences 详解
文章目录 SharedPreferences 详解基本概念获取 SharedPreferences 实例1. Context.getSharedPreferences()2. Activity.getPreferences()3. PreferenceManager.getDefaultSharedPreferences() 存储模式写入数据apply() vs commit() 读取数据监听数据变化最佳实践高级用法存储字…...
Qt基础006(事件)
文章目录 消息对话框QMessageBox快捷键开发基础 事件事件处理过程事件过滤器 消息对话框QMessageBox QMessageBox 是 Qt 框架中用于显示消息框的一个类,它常用于向用户显示信息、询问问题或者报告错 误。以下是 QMessageBox 的一些主要用途: 显示信息…...
Mediatek Android13 设置Launcher
概述: 本章将围绕Launcher讲述两种修改默认Launcher的情况。 一:完全覆盖 第一种方法和预置apk类似,区别在于增加LOCAL_OVERRIDES_PACKAGES说明,该方法会完全覆盖系统默认的Launcher。 关于如何预置apk,可见另一篇文章: Mediatek Android13 预置APP-CSDN博客 修改A…...
【Linux网络】构建基于UDP的简单聊天室系统
📢博客主页:https://blog.csdn.net/2301_779549673 📢博客仓库:https://gitee.com/JohnKingW/linux_test/tree/master/lesson 📢欢迎点赞 👍 收藏 ⭐留言 📝 如有错误敬请指正! &…...
【微知】git reset --soft --hard以及不加的区别?
背景 在 Git 里,git reset 是用来将当前的 HEAD 复位到指定状态的命令。--soft、--hard 是它的两个常用选项,本文简单介绍他们的区别,以及不添加选项时的默认情况。 在 Git 里,HEAD 是一个重要的引用,它指向当前所在的…...
制作一个简单的操作系统7
实模式下到保护模式下并打印 运行效果: 完整代码: 【免费】制作一个简单的操作系统7的源代码资源-CSDN文库https://download.csdn.net/download/farsight_2098/90670296 从零开始写操作系统引导程序:实模式到保护模式的跨越 引言 操作系统的启动过程是计算机系统中最神…...
2025企微CRM系统功能对比:会话存档、客户画像与数据分析如何重构客户运营?
一、企微CRM管理系统:从“连接工具”到“智能中枢” 随着企业微信生态的成熟,企微CRM管理软件已从简单的客户沟通渠道,升级为融合数据、策略与服务的核心平台。2025年,企业对企微CRM系统的需求聚焦于三大能力:会话存档…...