【链 表】

【链表】

  • 一级目录
      • 1. 基本概念
      • 2. 算法分析
        • 2.1 时间复杂度
        • 2.2 空间复杂度
        • 2.3 时空复杂度互换
      • 线性表的概念
      • 线性表的举例
      • 顺序表的基本概念
      • 顺序表的基本操作
        • 1. 初始化
        • 2. 插入操作
        • 3. 删除操作
        • 4. 查找操作
        • 5. 遍历操作
      • 顺序表的优缺点总结
        • 优点
        • 缺点
      • 树形结构
      • 图形结构
      • 单链表基本概念
      • 链表的分类
      • 单链表节点设置
        • Python 实现
        • C++ 实现
      • 单链表初始化
        • Python 实现
        • C++ 实现
      • 单链表增加节点
        • 尾部插入
        • Python 实现
        • C++ 实现
      • 单链表的遍历
        • Python 实现
        • C++ 实现
      • 单链表的销毁
        • Python 实现
        • C++ 实现
      • 链表的优缺点
        • 优点
        • 缺点
      • 循环链表
        • 循环链表节点设置与单链表相同,以下是循环链表初始化和尾部插入的 Python 示例:
      • 双向链表的概念
      • 基本操作
      • 节点设计
        • Python 实现
        • C++ 实现
      • 初始化
        • Python 实现
        • C++ 实现
      • 插入节点
        • Python 实现
        • C++ 实现
      • 剔除节点
        • Python 实现
        • C++ 实现
      • 链表的遍历
        • Python 实现
        • C++ 实现
      • 销毁链表
        • Python 实现
        • C++ 实现
      • 适用场合
      • 1. Linux 内核链表概述
      • 2. 容器与通用性
        • 容器概念
        • 通用性体现
      • 3. 节点的设计
      • 4. 增删操作
        • 初始化链表
        • 添加节点
        • 删除节点
      • 5. 查找结点
      • 6. 遍历链表
        • `list_for_each`
        • `list_for_each_entry`

一级目录

1. 基本概念

在计算机科学里,算法是为解决特定问题而设计的一系列明确且有限的指令。算法分析的核心目标是评估算法的效率与性能,一般从时间和空间两个维度展开。

  • 输入:算法运行所需的初始数据。
  • 输出:算法处理输入数据后得到的结果。
  • 确定性:算法的每个步骤都有明确的定义,不存在歧义。
  • 有穷性:算法必须在有限的步骤内结束。
  • 有效性:算法的每个步骤都能在有限时间内完成,并且是可行的。

在这里插入图片描述

2. 算法分析

2.1 时间复杂度

时间复杂度用于衡量算法执行所花费的时间随输入规模增长而变化的趋势,它不关注具体的执行时间,而是关注算法执行时间与输入规模之间的函数关系通常用大 O O O 符号来表示。

  • 常见时间复杂度
    • 常数时间复杂度 O ( 1 ) O(1) O(1):算法的执行时间不随输入规模的变化而变化。例如,访问数组中的某个元素:
def access_element(arr, index):return arr[index]
- **线性时间复杂度 $O(n)$**:算法的执行时间与输入规模 $n$ 成正比。例如,遍历数组中的每个元素:
def traverse_array(arr):for element in arr:print(element)
- **对数时间复杂度 $O(log n)$**:算法的执行时间随输入规模的对数增长。常见于二分查找算法:
def binary_search(arr, target):left, right = 0, len(arr) - 1while left <= right:mid = (left + right) // 2if arr[mid] == target:return midelif arr[mid] < target:left = mid + 1else:right = mid - 1return -1
- **平方时间复杂度 $O(n^2)$**:算法的执行时间与输入规模的平方成正比。例如,冒泡排序算法:
def bubble_sort(arr):n = len(arr)for i in range(n):for j in range(0, n - i - 1):if arr[j] > arr[j + 1]:arr[j], arr[j + 1] = arr[j + 1], arr[j]return arr
2.2 空间复杂度

空间复杂度用于衡量算法在执行过程中所占用的存储空间随输入规模增长而变化的趋势,同样用大 O O O 符号表示。

  • 常见空间复杂度
    • 常数空间复杂度 O ( 1 ) O(1) O(1):算法执行过程中所占用的存储空间不随输入规模的变化而变化。例如,交换两个变量的值:
def swap(a, b):temp = aa = bb = tempreturn a, b
- **线性空间复杂度 $O(n)$**:算法执行过程中所占用的存储空间与输入规模 $n$ 成正比。例如,创建一个长度为 $n$ 的数组:
def create_array(n):return [0] * n
2.3 时空复杂度互换

在算法设计中,时间复杂度和空间复杂度往往是相互制约的。有时候可以通过增加空间开销来降低时间复杂度,或者通过增加时间开销来减少空间复杂度,这就是时空复杂度互换。

  • 以空间换时间
    • 原理:利用额外的存储空间来存储中间结果或数据,从而减少重复计算,降低时间复杂度。
    • 示例:斐波那契数列的计算。传统的递归方法时间复杂度为 O ( 2 n ) O(2^n) O(2n),但可以使用动态规划的方法,通过一个数组来存储中间结果,将时间复杂度降低到 O ( n ) O(n) O(n),空间复杂度为 O ( n ) O(n) O(n)
def fibonacci(n):if n == 0 or n == 1:return ndp = [0] * (n + 1)dp[1] = 1for i in range(2, n + 1):dp[i] = dp[i - 1] + dp[i - 2]return dp[n]
  • 以时间换空间
    • 原理:减少存储空间的使用,通过重复计算或其他方式来弥补空间的不足,从而增加时间复杂度。
    • 示例:在某些情况下,如果不使用额外的数组来存储中间结果,而是在每次需要时重新计算,就可以减少空间开销,但会增加时间开销。例如,在计算斐波那契数列时,可以使用迭代方法,只使用常数级的额外空间,但时间复杂度仍然是 O ( n ) O(n) O(n)
def fibonacci_iterative(n):if n == 0 or n == 1:return na, b = 0, 1for i in range(2, n + 1):a, b = b, a + breturn b

综上所述,算法分析中的时间复杂度、空间复杂度以及时空复杂度互换是设计和评估算法的重要概念,需要根据具体的问题和场景来选择合适的算法和策略。

线性表的概念

线性表(Linear List)是一种最基本、最简单的数据结构,它是由 n n n n ≥ 0 n \geq 0 n0)个数据元素(节点)组成的有限序列。

其中,除第一个元素外,每个元素都有且仅有一个直接前驱;除最后一个元素外,每个元素都有且仅有一个直接后继。数据元素之间呈现出一对一的线性关系。
在这里插入图片描述

线性表的举例

  • 学生信息表:假设要管理一个班级学生的信息,每个学生信息包含学号、姓名、年龄等。可以将每个学生的信息看作一个数据元素,这些学生信息按一定顺序排列就构成了一个线性表。例如,按照学号从小到大的顺序排列所有学生信息。
  • 图书列表:在图书馆管理系统中,每本图书的信息(如书名、作者、ISBN 号等)是一个数据元素,所有图书信息组成的列表就是一个线性表。

顺序表的基本概念

顺序表(Sequential List)是线性表的一种顺序存储结构,它是用一组地址连续的存储单元依次存储线性表中的各个数据元素,使得逻辑上相邻的数据元素在物理位置上也相邻。在高级编程语言中,通常使用数组来实现顺序表。

顺序表的基本操作

1. 初始化

创建一个空的顺序表,通常需要分配一定的存储空间。以下是 Python 代码示例:

class SeqList:def __init__(self, max_size=100):self.max_size = max_sizeself.data = [None] * max_sizeself.length = 0
2. 插入操作

在顺序表的指定位置插入一个新的数据元素。插入操作可能需要移动元素以腾出插入位置。以下是插入操作的代码示例:

    def insert(self, index, value):if index < 0 or index > self.length:return Falseif self.length >= self.max_size:return Falsefor i in range(self.length, index, -1):self.data[i] = self.data[i - 1]self.data[index] = valueself.length += 1return True
3. 删除操作

删除顺序表中指定位置的数据元素。删除操作后,需要将后续元素前移以填补空缺。以下是删除操作的代码示例:

    def delete(self, index):if index < 0 or index >= self.length:return Falsefor i in range(index, self.length - 1):self.data[i] = self.data[i + 1]self.length -= 1return True
4. 查找操作

根据给定的值或位置查找顺序表中的数据元素。以下是按值查找的代码示例:

    def search(self, value):for i in range(self.length):if self.data[i] == value:return ireturn -1
5. 遍历操作

依次访问顺序表中的每个数据元素。以下是遍历操作的代码示例:

    def traverse(self):for i in range(self.length):print(self.data[i], end=" ")print()

顺序表的优缺点总结

在这里插入图片描述

优点
  • 随机访问效率高:由于顺序表使用数组存储,通过数组下标可以直接访问任意位置的元素,时间复杂度为 O ( 1 ) O(1) O(1)。例如,要访问顺序表中第 i i i 个元素,直接通过数组下标 i i i 即可快速定位。
  • 存储密度大:顺序表中只存储数据元素本身,不需要额外的指针来表示元素之间的逻辑关系,因此存储密度为 1,空间利用率高。
缺点

**

  • 插入和删除操作效率低:在顺序表中进行插入和删除操作时,通常需要移动大量元素,平均时间复杂度为 O ( n ) O(n) O(n)。例如,在顺序表的开头插入一个元素,需要将后面的所有元素依次后移一位。
  • 空间分配不灵活:顺序表在初始化时需要预先分配一定的存储空间,如果预先分配的空间过大,会造成空间浪费;如果预先分配的空间过小,又可能导致数据溢出。并且,在运行过程中难以动态调整存储空间的大小。

**

树形结构

- **概念**:非线性数据结构,由节点和边组成,有根节点,除根外每个节点有一个父节点,可有多子节点,无环。
- **特点**:层次分明,呈一对多关系。
- **常见类型**:二叉树、二叉搜索树、AVL 树、红黑树、B 树和 B + 树等。
- **应用**:用于文件系统组织、数据库索引、编译原理中的语法分析等。

图形结构

- **概念**:比树形结构复杂的非线性结构,由顶点和边构成,边可有无方向、可带权重。
- **特点**:顶点关系多对多,可能存在环。
- **常见类型**:无向图、有向图、带权图。
- **应用**:适用于社交网络分析、交通网络路径规划、电路设计等。 

在这里插入图片描述

单链表基本概念

单链表是一种常见的线性数据结构,它由一系列节点组成。每个节点包含两部分:数据域和指针域。数据域用于存储实际的数据,指针域存储指向下一个节点的指针(地址)。链表的第一个节点称为头节点,最后一个节点的指针域通常指向空(NULLNone),以此表示链表的结束

在这里插入图片描述

链表的分类

  • 单链表:节点只有一个指向下一个节点的指针,只能单向遍历。
  • 双向链表:每个节点除了有指向下一个节点的指针外,还有一个指向前一个节点的指针,可双向遍历。
  • 循环链表:单链表或双向链表的最后一个节点的指针域指向头节点,形成一个环。
    在这里插入图片描述

单链表节点设置

在这里插入图片描述
在这里插入图片描述

以下是用 Python 和 C++ 实现单链表节点的示例:

Python 实现
class Node:def __init__(self, data):self.data = data  # 数据域self.next = None  # 指针域,初始化为 None
C++ 实现
#include <iostream>struct Node {int data;  // 数据域Node* next;  // 指针域Node(int value) : data(value), next(nullptr) {}  // 构造函数
};

单链表初始化

初始化一个单链表通常是创建一个头节点,其数据域可以不存储实际数据,仅作为链表的起始标识。

Python 实现
class LinkedList:def __init__(self):self.head = None  # 初始化头节点为 None
C++ 实现
class LinkedList {
private:Node* head;
public:LinkedList() : head(nullptr) {}  // 构造函数,初始化头节点为 nullptr
};

单链表增加节点

尾部插入

在链表尾部添加新节点。

Python 实现
class LinkedList:def __init__(self):self.head = Nonedef append(self, data):new_node = Node(data)if not self.head:self.head = new_nodereturnlast_node = self.headwhile last_node.next:last_node = last_node.nextlast_node.next = new_node
C++ 实现
class LinkedList {
private:Node* head;
public:LinkedList() : head(nullptr) {}void append(int data) {Node* new_node = new Node(data);if (!head) {head = new_node;return;}Node* last_node = head;while (last_node->next) {last_node = last_node->next;}last_node->next = new_node;}
};

单链表的遍历

依次访问链表中的每个节点并处理其数据。

Python 实现
class LinkedList:# ... 前面的代码 ...def traverse(self):current_node = self.headwhile current_node:print(current_node.data)current_node = current_node.next
C++ 实现
class LinkedList {// ... 前面的代码 ...void traverse() {Node* current_node = head;while (current_node) {std::cout << current_node->data << std::endl;current_node = current_node->next;}}
};

单链表的销毁

释放链表中所有节点占用的内存。

Python 实现
class LinkedList:# ... 前面的代码 ...def destroy(self):current_node = self.headwhile current_node:next_node = current_node.nextdel current_nodecurrent_node = next_nodeself.head = None
C++ 实现
class LinkedList {// ... 前面的代码 ...~LinkedList() {Node* current_node = head;while (current_node) {Node* next_node = current_node->next;delete current_node;current_node = next_node;}head = nullptr;}
};

链表的优缺点

优点
  • 动态内存分配链表可以在运行时动态分配和释放内存,不需要预先分配固定大小的空间,适合存储数量不确定的数据
  • 插入和删除效率高:在链表中插入或删除节点,只需要修改指针,时间复杂度为 O ( 1 ) O(1) O(1)(前提是已知要操作的节点位置)。
缺点
  • 随机访问效率低链表不支持随机访问,要访问链表中的某个节点,必须从头节点开始依次遍历,时间复杂度为 O ( n ) O(n) O(n)
  • 额外的指针开销:每个节点需要额外的指针域来存储指向下一个节点的地址,增加了内存开销。

循环链表

循环链表是一种特殊的链表,它的最后一个节点的指针域指向头节点,形成一个环。与单链表相比,循环链表可以从任意节点开始遍历整个链表。
在这里插入图片描述

循环链表节点设置与单链表相同,以下是循环链表初始化和尾部插入的 Python 示例:
class Node:def __init__(self, data):self.data = dataself.next = Noneclass CircularLinkedList:def __init__(self):self.head = Nonedef append(self, data):new_node = Node(data)if not self.head:self.head = new_nodenew_node.next = self.headreturnlast_node = self.headwhile last_node.next != self.head:last_node = last_node.nextlast_node.next = new_nodenew_node.next = self.head

循环链表在某些场景下很有用,例如实现循环队列、约瑟夫环问题等。

双向链表的概念

双向链表(Doubly Linked List)是一种线性数据结构,它是在单链表的基础上进行扩展。

每个节点除了包含数据域和指向下一个节点的指针(后继指针)外, 还包含一个指向前一个节点的指针(前驱指针)。

这种结构使得双向链表可以从两个方向进行遍历,既可以从链表头开始向后遍历,也可以从链表尾开始向前遍历。
在这里插入图片描述

在这里插入图片描述

基本操作

双向链表的基本操作包括初始化、插入节点、剔除节点、遍历链表以及销毁链表等。

节点设计

以下是使用 Python 和 C++ 实现双向链表节点的示例:

Python 实现
class Node:def __init__(self, data):self.data = data  # 数据域self.prev = None  # 前驱指针,初始化为 Noneself.next = None  # 后继指针,初始化为 None
C++ 实现
#include <iostream>struct Node {int data;  // 数据域Node* prev;  // 前驱指针Node* next;  // 后继指针Node(int value) : data(value), prev(nullptr), next(nullptr) {}  // 构造函数
};

初始化

初始化双向链表通常是创建一个头节点,该头节点的数据域可以不存储实际数据,仅作为链表的起始标识。

Python 实现
class DoublyLinkedList:def __init__(self):self.head = None  # 初始化头节点为 None
C++ 实现
class DoublyLinkedList {
private:Node* head;
public:DoublyLinkedList() : head(nullptr) {}  // 构造函数,初始化头节点为 nullptr
};

插入节点

插入节点可以分为在链表头部插入、在链表尾部插入和在指定位置插入等情况。以下以在链表尾部插入为例:

Python 实现
class DoublyLinkedList:def __init__(self):self.head = Nonedef append(self, data):new_node = Node(data)if not self.head:self.head = new_nodereturnlast_node = self.headwhile last_node.next:last_node = last_node.nextlast_node.next = new_nodenew_node.prev = last_node
C++ 实现
class DoublyLinkedList {
private:Node* head;
public:DoublyLinkedList() : head(nullptr) {}void append(int data) {Node* new_node = new Node(data);if (!head) {head = new_node;return;}Node* last_node = head;while (last_node->next) {last_node = last_node->next;}last_node->next = new_node;new_node->prev = last_node;}
};

剔除节点

剔除节点时需要处理好前驱和后继指针的关系,以保证链表的连贯性。以下是删除指定值节点的示例:

Python 实现
class DoublyLinkedList:# ... 前面的代码 ...def delete(self, key):current = self.headwhile current:if current.data == key:if current.prev:current.prev.next = current.nextelse:self.head = current.nextif current.next:current.next.prev = current.prevreturncurrent = current.next
C++ 实现
class DoublyLinkedList {// ... 前面的代码 ...void deleteNode(int key) {Node* current = head;while (current) {if (current->data == key) {if (current->prev) {current->prev->next = current->next;} else {head = current->next;}if (current->next) {current->next->prev = current->prev;}delete current;return;}current = current->next;}}
};

链表的遍历

双向链表可以从前往后或从后往前遍历。以下是从前往后遍历的示例:

Python 实现
class DoublyLinkedList:# ... 前面的代码 ...def traverse_forward(self):current = self.headwhile current:print(current.data)current = current.next
C++ 实现
class DoublyLinkedList {// ... 前面的代码 ...void traverseForward() {Node* current = head;while (current) {std::cout << current->data << std::endl;current = current->next;}}
};

销毁链表

释放链表中所有节点占用的内存。

Python 实现
class DoublyLinkedList:# ... 前面的代码 ...def destroy(self):current = self.headwhile current:next_node = current.nextdel currentcurrent = next_nodeself.head = None
C++ 实现
class DoublyLinkedList {// ... 前面的代码 ...~DoublyLinkedList() {Node* current = head;while (current) {Node* next_node = current->next;delete current;current = next_node;}head = nullptr;}
};

适用场合

  • 需要双向遍历的场景:当需要频繁地从两个方向访问数据时,双向链表非常合适。例如,在文本编辑器中实现撤销和重做功能,双向链表可以方便地记录操作历史,向前遍历可以实现撤销操作,向后遍历可以实现重做操作。
  • 需要高效删除节点的场景:在双向链表中删除一个节点时,由于可以直接访问其前驱节点,不需要像单链表那样从头节点开始遍历找到前驱节点,因此删除操作更加高效。例如,在实现
    LRU(Least Recently Used)缓存算法时,双向链表结合哈希表可以高效地实现缓存的淘汰机制。

1. Linux 内核链表概述

Linux 内核链表是一种非常经典且高效的数据结构实现,它采用了一种独特的设计方式,将链表节点嵌入到其他数据结构中,从而实现了链表的通用性和灵活性。这种设计使得链表可以方便地管理各种不同类型的数据,避免了为每种数据类型都单独实现一个链表的繁琐工作。

2. 容器与通用性

容器概念

在 Linux 内核链表中,“容器”指的是包含链表节点的数据结构。链表节点并不是直接存储数据,而是作为一个成员嵌入到其他结构体中。通过这种方式,链表可以将不同类型的数据组织起来,这些包含链表节点的结构体就像是一个个“容器”,链表节点则是连接这些容器的纽带

通用性体现

由于链表节点不依赖于具体的数据类型,只要在自定义的数据结构中包含 list_head 结构体,就可以将这些数据结构添加到链表中进行管理。这使得内核链表可以用于管理各种不同类型的数据,如进程描述符、文件描述符等,大大提高了代码的复用性和可维护性。

3. 节点的设计

Linux 内核链表的节点由 list_head 结构体表示,其定义位于 <linux/list.h> 头文件中,代码如下:

struct list_head {struct list_head *next, *prev;
};

这个结构体只包含两个指针,分别指向前一个节点和后一个节点,不包含任何数据域。当需要使用链表来管理数据时,只需要在自定义的数据结构中包含一个 list_head 成员即可。例如:

struct my_data {int value;struct list_head list;  // 嵌入链表节点
};

4. 增删操作

初始化链表

在使用链表之前,需要对链表进行初始化。可以使用 INIT_LIST_HEAD 宏来初始化一个链表头:

#include <linux/list.h>struct list_head my_list;
INIT_LIST_HEAD(&my_list);
添加节点

Linux 内核提供了几个宏来实现节点的添加操作,常用的有 list_addlist_add_tail

  • list_add:将新节点添加到指定节点之后,通常用于在链表头部插入节点。
struct my_data *new_node = kmalloc(sizeof(struct my_data), GFP_KERNEL);
new_node->value = 10;
list_add(&new_node->list, &my_list);
  • list_add_tail:将新节点添加到指定节点之前,通常用于在链表尾部插入节点。
struct my_data *new_node = kmalloc(sizeof(struct my_data), GFP_KERNEL);
new_node->value = 20;
list_add_tail(&new_node->list, &my_list);
删除节点

使用 list_del 宏可以从链表中删除一个节点:

struct my_data *node_to_delete;
// 假设 node_to_delete 指向要删除的节点
list_del(&node_to_delete->list);
kfree(node_to_delete);

5. 查找结点

Linux 内核链表本身并没有提供专门的查找函数,因为链表节点不包含数据域,查找操作通常需要结合具体的数据结构来实现。可以通过遍历链表,比较每个节点所包含的数据来查找符合条件的节点。例如,查找 value 等于某个特定值的节点:

struct my_data *entry;
list_for_each_entry(entry, &my_list, list) {if (entry->value == target_value) {// 找到目标节点break;}
}

6. 遍历链表

Linux 内核提供了几个宏来方便地遍历链表,常用的有 list_for_eachlist_for_each_entry

list_for_each

用于遍历链表节点,它只操作 list_head 结构体:

struct list_head *pos;
list_for_each(pos, &my_list) {// 处理节点
}
list_for_each_entry

用于遍历包含链表节点的数据结构,它会根据链表节点的地址计算出包含该节点的数据结构的地址:

struct my_data *entry;
list_for_each_entry(entry, &my_list, list) {printk(KERN_INFO "Value: %d\n", entry->value);
}

综上所述,Linux 内核链表通过巧妙的设计实现了高度的通用性和灵活性,为内核中的数据管理提供了强大而高效的工具。

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

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

相关文章

python-leetcode-字符串解码

394. 字符串解码 - 力扣&#xff08;LeetCode&#xff09; class Solution:def decodeString(self, s: str) -> str:stack []num 0curr_str ""for char in s:if char.isdigit():num num * 10 int(char)elif char [:stack.append((curr_str, num))curr_str, …

力扣 下一个排列

交换位置&#xff0c;双指针&#xff0c;排序。 题目 下一个排列即在组成的排列中的下一个大的数&#xff0c;然后当这个排列为降序时即这个排列最大&#xff0c;因为大的数在前面&#xff0c;降序排列的下一个数即升序。所以&#xff0c;要是想找到当前排列的下一个排列&…

ProGuard加密混淆SpringBoot应用代码

背景 我们的项目是基于SpringCloud架构的微服务应用&#xff0c;采用Docker离线部署方式交付客户&#xff0c;通过授权证书来控制应用的许可功能模块和使用时间。我们已经在代码层已经实现&#xff1a; 基于多维度硬件指纹的绑定验证&#xff0c;cpu id、mac地址、磁盘序列、…

动态链接器(九):.init和.init_array

ELF文件中的.init和.init_array段是程序初始化阶段的重要组成部分&#xff0c;用于在main函数执行前完成必要的初始化操作。 1 .init段和.init_array 段 1.1 作用 .init段包含编译器生成的初始化代码&#xff0c;通常由运行时环境&#xff08;如C标准库的启动例程&#xff0…

Ollama微调

Ollama是一款开源工具&#xff0c;其目标是简化大语言模型在本地环境的部署和使用。它支持多种流行的开源大语言模型&#xff0c;如 Llama 2、Qwen2.5等。在上一篇文章中我们部署Ollama&#xff0c;并使用简单命令管理Ollama。接下来我们学习Ollama的高级应用。通过Ollama的Mod…

DeepSeek开源周Day1:FlashMLA引爆AI推理性能革命!

项目地址&#xff1a;GitHub - deepseek-ai/FlashMLA 开源日历&#xff1a;2025-02-24起 每日9AM(北京时间)更新&#xff0c;持续五天&#xff01; ​ 一、开源周震撼启幕 继上周预告后&#xff0c;DeepSeek于北京时间今晨9点准时开源「FlashMLA」&#xff0c;打响开源周五连…

(七)懒加载预加载

&#xff08;一&#xff09;懒加载 1. 什么是懒加载 懒加载&#xff0c;即延迟加载。在访问页面时&#xff0c;先将 img 元素或其他元素的背景图片路径替换为占位图&#xff08;通常是 1*1px 的小图片&#xff09;&#xff0c;仅当元素进入浏览器可视区域时&#xff0c;才设置…

Revisiting Reverse Distillation for Anomaly Detection

重新审视反向蒸馏在异常检测中的应用 文章链接&#xff1a;点这里 源码链接&#xff1a;点这里 前言 此篇文章是在 Anomaly detection via reverse distillation from one-class embedding 这篇的基础上改进创新的。重新审视了反向蒸馏&#xff08;KD&#xff09;这一想法&am…

Windows CMD 命令大全(Complete List of Windows CMD Commands)

Windows CMD 命令大全&#xff1a; Windows CMD 是 Windows 系统内置的命令行工具&#xff0c;用于执行各种命令和管理任务。 称为Command Prompt。它提供了一个通过键入命令来与计算机系统进行交互的方式&#xff0c;类似于早期的DOS操作系统。以下是 CMD 的基础知识和常用命…

hot100-二叉树

二叉树 二叉树递归 相当于这个的顺序来回调换 class Solution {private List<Integer> res new ArrayList<>();public List<Integer> inorderTraversal(TreeNode root) {if(root null)return res;inorderTraversal(root.left);res.add(root.val);inorde…

【JavaWeb13】了解ES6的核心特性,对于提高JavaScript编程效率有哪些潜在影响?

文章目录 &#x1f30d;一. ES6 新特性❄️1. ES6 基本介绍❄️2. 基本使用2.1 let 声明变量2.2 const 声明常量/只读变量2.3 解构赋值2.4 模板字符串2.5 对象拓展运算符2.6 箭头函数 &#x1f30d;二. Promise❄️1. 基本使用❄️2. 如何解决回调地狱问题2.1回调地狱问题2.2 使…

ROS的action通信——实现阶乘运算(三)

在ROS中除了常见的话题(topic&#xff09;通信、服务(server)通信等方式&#xff0c;还有action通信这一方式&#xff0c;由于可以实时反馈任务完成情况&#xff0c;该通信方式被广泛运用于机器人导航等任务中。本文将通过三个小节的分享&#xff0c;实现基于action通信的阶乘运…

centos系统MBR格式转换成gpt格式 (华为云)

在华为云上的centos7.9系统MBR格式转换成GPT格式的步骤 华为云上关于转换的步骤 这个链接里面 gdisk -g /dev/vda 是不对的&#xff0c;-g参数是新创建一个分区&#xff0c;慎用 自己步骤如下&#xff1a;&#xff08;已经试验过&#xff09; 1、gdisk /dev/sda (这里是盘 不…

【Microsoft PowerPoint for Mac】2分钟配置-MAC一键删除PPT中的所有备注

MAC一键删除PPT中的所有备注 1.搜索自动操作2.点击快速操作3.搜索并运行AppleScript4.输入代码&#xff0c;并选择只应用于Microsoft PowerPoint for Mac【右上角】5. CRTLS保存为“清除当前文稿中的所有备注”&#xff0c;PPT中应用。 MAC没自带&#xff0c;需要自己配置 1.搜…

uni-app 开发 App 、 H5 横屏签名(基于lime-signature)

所用插件&#xff1a;lime-signature 使用到 CSS 特性 绝对定位transform 旋转transform-origin transform 原点 复习一下定位元素&#xff08;相对定位、绝对定位、粘性定位&#xff09; 代码# <template><view class"signature-page"><view clas…

【Linux探索学习】第三十一弹——线程互斥与同步(下):深入理解确保线程安全的机制

线程互斥与同步&#xff08;上&#xff09;&#xff1a;【Linux探索学习】第三十弹——线程互斥与同步&#xff08;上&#xff09;&#xff1a;深入理解线程保证安全的机制-CSDN博客 Linux探索学习&#xff1a; https://blog.csdn.net/2301_80220607/category_12805278.html?…

《Effective Objective-C》阅读笔记(中)

目录 接口与API设计 用前缀避免命名空间冲突 提供“全能初始化方法” 实现description方法 尽量使用不可变对象 使用清晰而协调的命名方式 方法命名 ​编辑类与协议命名 为私有方法名加前缀 理解OC错误模型 理解NSCopying协议 协议与分类 通过委托与数据源协议进行…

python-leetcode-每日温度

739. 每日温度 - 力扣&#xff08;LeetCode&#xff09; class Solution:def dailyTemperatures(self, temperatures: List[int]) -> List[int]:n len(temperatures)answer [0] * nstack [] # 存储索引for i, temp in enumerate(temperatures):while stack and temperat…

山东大学软件学院nosql实验三

实验题目&#xff1a; 用Java做简单查询(2学时) 实验内容 用API方式&#xff0c;做简单查询。 实验要求 在以下要求中选择至少2个&#xff0c;使用Java语言实现数据查询&#xff0c;最终把数据输出到前端界面。 &#xff08;1&#xff09;找出年龄小于20岁的所有学生 &…

【Linux】初探信号的奥秘

目录 一、引入信号&#xff1a; 1、什么是信号&#xff1a; 二、前后台进程&#xff1a; 三、信号的处理方式&#xff1a; 四、键盘数据与信号&#xff1a; 前言&#xff1a; 在Linux系统编程中&#xff0c;信号&#xff08;Signal&#xff09;是一种至关重要的进程间通信…