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

【JS常见数据结构】

JS数据结构

  • 前言
    • 数组
      • JavaScript 中数组的常见操作:
        • 1. 创建数组:
        • 2. 访问数组元素:
        • 3. 插入元素:
        • 4. 删除元素:
        • 5. 查询元素:
    • 链表
        • 单向链表
        • 双向链表
        • 循环链表
    • 队列
        • 二叉树示例
      • 图的定义
      • 图的分类
      • 图的表示方法
        • 邻接矩阵
        • 邻接表
        • 关联矩阵
      • 图的遍历
        • 深度优先遍历
        • 广度优先遍历
      • 图的常见算法
        • 最短路径算法
        • 拓扑排序算法

前言

JavaScript数据结构是指数据的组织方式

常见的数据结构包括数组、链表、栈、队列、树、图等。在JavaScript中,数组是最常见和最基础的数据结构,而链表、栈和队列等数据结构则需要通过对象和数组等方式进行模拟。

数组

数组是一种线性数据结构,由一系列连续的空间组成,用于存储一组具有相同数据类型的元素。数组是最简单、最基础的数据结构之一,它的操作通常包括访问、插入、删除和查找。

JavaScript 中的数组是一种特殊的对象,可以通过索引来访问元素,索引从 0 开始计数。JavaScript 数组可以存储任意类型的数据,包括数字、字符串、布尔值和对象等。同时也支持动态调整数组的长度,即在数组末尾添加或删除元素。

JavaScript 中数组的常见操作:

1. 创建数组:

let arr = []; // 创建一个空数组
let arr2 = [1, 2, 3, 4, 5]; // 创建一个包含五个元素的数组

2. 访问数组元素:

let arr = [1, 2, 3, 4, 5];
console.log(arr[2]); // 3

3. 插入元素:

let arr = [1, 2, 3, 4, 5];
arr.push(6); // 在末尾添加元素
arr.unshift(0); // 在开头添加元素
arr.splice(2, 0, 2.5); // 在指定位置插入元素

4. 删除元素:

let arr = [1, 2, 3, 4, 5];
arr.pop(); // 删除末尾元素
arr.shift(); // 删除开头元素
arr.splice(2, 1); // 删除指定位置的元素

5. 查询元素:

let arr = [1, 2, 3, 4, 5];
console.log(arr.indexOf(3)); // 2
console.log(arr.includes(6)); // false

JavaScript 的数组还有一些高阶函数,如 map、filter、reduce 等,可用于快速地操作数组中的元素。同时也可以利用数组进行栈、队列等数据结构的实现。
JS 常用的数组方法有:

  1. push():将一个或多个元素添加到数组末尾。
  2. pop():删除数组的最后一个元素。
  3. unshift():将一个或多个元素添加到数组开头。
  4. shift():删除数组的第一个元素。
  5. splice():在指定位置插入或删除元素。
  6. slice():从数组中截取指定部分的元素。
  7. concat():连接两个或多个数组。
  8. join():将数组中的元素以指定的分隔符连接成字符串。
  9. reverse():反转数组中元素的顺序。
  10. sort():按照指定的排序规则对数组中的元素进行排序。
  11. indexOf():返回指定元素在数组中第一次出现的索引。
  12. lastIndexOf():返回指定元素在数组中最后一次出现的索引。
  13. filter():返回一个新数组,其中包含符合指定条件的所有元素。
  14. map():返回一个新数组,其中包含对原数组的每个元素进行操作后的结果。
  15. reduce():对数组中的所有元素进行累加或累积计算,返回计算结果。
  16. forEach():对数组中的每个元素执行指定的操作。

链表

链表是一种常见的数据结构,用于存储一系列元素。它由一系列的节点(Node)组成,每个节点包含一个数据元素和一个指向下一个节点的指针。

链表与数组相比,具有以下优点:

  • 链表可以在任何位置添加或删除元素,而数组需要移动元素来完成这些操作;
  • 链表可以动态分配空间,而数组的大小是固定的;
  • 链表的查找和访问效率比数组差。

链表通常分为单向链表、双向链表和循环链表三种。

单向链表

单向链表是最基本的链表类型,每个节点只有一个指针指向下一个节点,最后一个节点的指针指向 null。

JavaScript 实现单向链表可以使用对象字面量或者构造函数:

// 对象字面量实现单向链表
let node1 = { data: 1, next: null };
let node2 = { data: 2, next: null };
let node3 = { data: 3, next: null };node1.next = node2;
node2.next = node3;// 构造函数实现单向链表
class Node {constructor(data) {this.data = data;this.next = null;}
}let node1 = new Node(1);
let node2 = new Node(2);
let node3 = new Node(3);node1.next = node2;
node2.next = node3;

双向链表

双向链表每个节点有两个指针,一个指向前一个节点,一个指向后一个节点。

JavaScript 实现双向链表可以参考以下代码:

class Node {constructor(data) {this.data = data;this.prev = null;this.next = null;}
}class DoublyLinkedList {constructor() {this.head = null;this.tail = null;}add(data) {let node = new Node(data);if (!this.head) {this.head = node;} else {this.tail.next = node;node.prev = this.tail;}this.tail = node;}remove(data) {let current = this.head;while (current) {if (current.data === data) {if (current === this.head && current === this.tail) {this.head = null;this.tail = null;} else if (current === this.head) {this.head = this.head.next;this.head.prev = null;} else if (current === this.tail) {this.tail = this.tail.prev;this.tail.next = null;} else {current.prev.next = current.next;current.next.prev = current.prev;}}current = current.next;}}
}

循环链表

循环链表是一种特殊的链表,它的最后一个节点的指针不是 null,而是指向第一个节点。循环链表可以用于模拟环形结构。

JavaScript 实现循环链表可以参考以下代码:

class Node {constructor(data) {this.data = data;this.next = null;}
}class CircularLinkedList {constructor() {this.head = null;this.tail = null;}add(data) {let node = new Node(data);if (!this.head) {this.head = node;} else {this.tail.next = node;}this.tail = node;this.tail.next = this.head;}remove(data) {let current = this.head;let previous = null;while (current) {if (current === this.head && current === this.tail) {this.head = null;this.tail = null;break;} else if (current === this.head) {this.head = this.head.next;this.tail.next = this.head;} else if (current === this.tail) {previous.next = this.head;this.tail = previous;} else {previous.next = current.next;}previous = current;current = current.next;}}
}

以上就是 JavaScript 实现链表的基本介绍和示例代码。在实际开发中,链表通常用于实现诸如 LRU 缓存、哈希表等数据结构。

栈是一种后进先出(LIFO)的数据结构,它可以用数组或链表来实现。在栈中,最后插入的元素被称为栈顶,而最早插入的元素被称为栈底。栈的基本操作包括入栈(push)和出栈(pop)两个操作。

入栈操作是将元素添加到栈顶,并更新栈顶位置,而出栈操作则是将栈顶元素删除,并更新栈顶位置。其他常用操作包括访问栈顶元素(peek),获取栈的大小(size)和判断栈是否为空(isEmpty)。

栈在计算机领域应用广泛,例如在程序调用栈中,每当函数被调用时都会将其返回地址等信息压入栈中,函数执行完毕后再将这些信息弹出以返回到调用点;在表达式的求值中,栈可以用来记录运算符和操作数,完成中缀表达式转换为后缀表达式等操作。

下面是栈的 JavaScript 实现:

class Stack {constructor() {this.items = [];this.top = -1;}push(element) {this.items[++this.top] = element;}pop() {if (this.isEmpty()) return null;return this.items[this.top--];}peek() {if (this.isEmpty()) return null;return this.items[this.top];}size() {return this.top + 1;}isEmpty() {return this.top === -1;}clear() {this.items = [];this.top = -1;}
}

在这个实现中,使用了数组来存储栈元素,变量this.top表示栈顶位置。push操作利用了 JavaScript 数组自带的push方法,在栈顶插入元素并更新栈顶位置;pop操作利用了数组自带的pop方法,删除栈顶元素并更新栈顶位置,同时如果栈为空则返回nullpeek操作返回栈顶元素,如果栈为空则返回nullsize操作返回栈大小,即栈中元素个数;isEmpty操作判断栈是否为空;clear操作清空栈,即将栈数组和栈顶位置重置为初始状态。

队列

队列是一种线性数据结构,可用于在一端添加元素(队尾),在另一端删除元素(队首)。队列遵循先进先出(FIFO)原则,即先加入队列的元素先被删除。

队列的常用操作包括:

  • 入队(enqueue):将元素添加到队列的末尾。
  • 出队(dequeue):从队列的头部删除元素并返回。
  • 队首(peek):返回队列头部元素,但不删除它。
  • 队列元素个数(size):返回队列中元素的个数。
  • 队列是否为空(isEmpty):判断队列是否为空。

队列的实现方式有多种,常见的有数组和链表。

数组实现队列:

class Queue {constructor() {this.items = [];}enqueue(item) {this.items.push(item);}dequeue() {if (this.items.length === 0) {return null;}return this.items.shift();}peek() {if (this.items.length === 0) {return null;}return this.items[0];}size() {return this.items.length;}isEmpty() {return this.items.length === 0;}
}

链表实现队列:

class Node {constructor(item) {this.item = item;this.next = null;}
}class Queue {constructor() {this.head = null;this.tail = null;this.length = 0;}enqueue(item) {const node = new Node(item);if (this.length === 0) {this.head = node;this.tail = node;} else {this.tail.next = node;this.tail = node;}this.length++;}dequeue() {if (this.isEmpty()) {return null;}const item = this.head.item;this.head = this.head.next;this.length--;return item;}peek() {if (this.isEmpty()) {return null;}return this.head.item;}size() {return this.length;}isEmpty() {return this.length === 0;}
}

树是一种非常常见的数据结构。树结构呈现出有层次的关系,由根节点开始,每个节点可以有多个子节点,但每个节点只能有一个父节点。

树的组成部分包括:节点、边和路径。

节点:树中的每个元素称为一个节点。每个节点包括一个值和指向它的子节点的引用。

边:节点之间的链接称为边,边表示节点之间的关系。

路径:路径是连接两个节点的边的序列。

树有很多种类,每种树都有自己的特定性质和用途。以下是一些常见的树:

  • 二叉树:每个节点最多有两个子节点。
  • 二叉搜索树:是一种特殊的二叉树,左子树上所有节点的值都小于根节点的值,右子树上所有节点的值都大于根节点的值。
  • AVL 树:是一种平衡二叉搜索树,使得所有叶子节点到根节点的路径上的高度差最多为 1。
  • B 树:一种多路搜索树,每个节点可以有多个子节点。
  • 红黑树:是一种自平衡二叉搜索树,能够保证任何一个节点的左右子树高度差小于两倍。

二叉树示例

其中每个节点最多有两个子节点:一个左子节点和一个右子节点。二叉树常用于搜索和排序操作,以及表示表达式和编译器中的语法树。

在 JavaScript 中,可以使用对象来表示二叉树。每个节点都是一个对象,包含一个 value 属性表示节点的值,以及 left 和 right 属性,分别表示该节点的左子节点和右子节点。

以下是一个简单的例子:

class Node {constructor(value) {this.value = value;this.left = null;this.right = null;}
}const root = new Node(1);
root.left = new Node(2);
root.right = new Node(3);
root.left.left = new Node(4);
root.left.right = new Node(5);

以上代码创建了一个二叉树,根节点的值为 1,左子节点的值为 2,右子节点的值为 3。2 的左子节点的值为 4,右子节点的值为 5。

遍历二叉树是常见的操作之一。以下是三种遍历方式的实现:

// 前序遍历
function preOrder(root) {if (!root) return;console.log(root.value);preOrder(root.left);preOrder(root.right);
}// 中序遍历
function inOrder(root) {if (!root) return;inOrder(root.left);console.log(root.value);inOrder(root.right);
}// 后序遍历
function postOrder(root) {if (!root) return;postOrder(root.left);postOrder(root.right);console.log(root.value);
}

前序遍历先访问根节点,然后访问左子树,最后访问右子树。中序遍历先访问左子树,然后访问根节点,最后访问右子树。后序遍历先访问左子树,然后访问右子树,最后访问根节点。
除了遍历,二叉树还可以进行插入、删除等操作。这些操作通常需要对树进行递归遍历和修改。

树的应用非常广泛,比如在计算机科学中,树被广泛地应用于搜索算法、排序算法、编译器、操作系统、数据库、人工智能和网络技术等领域。

图是一种非常重要的数据结构,由节点和边组成,一些常用的应用包括社交网络分析、路线规划等。下面我将为你详细介绍图的相关概念和示例,希望能帮助你更好地理解。

图的定义

图是由节点和边组成的一种非线性数据结构,它是一组二元关系的集合。节点也称为顶点,边用于连接节点,表示它们之间的关系。每个节点可以有多个相邻节点,这些节点通过边连接在一起。

图可以由以下元素组成:

  • 节点(顶点):表示图中的对象,可以是任何对象;
  • 边:连接节点之间的线段,表示节点之间的关系;
  • 权重:每条边上的权重,表示两个节点之间的距离或者代价;
  • 路径:由边连接的一组节点;
  • 网络:由边连接的一组节点和它们的权重。

图的分类

图可以按照有无方向、有无边权、有无环等特性进行分类。

按照有无方向,图可以分为有向图和无向图。有向图中,每条边都有一个方向,从一个节点指向另一个节点。无向图中,每条边没有方向,两个节点之间的关系是相互的。

按照有无边权,图可以分为带权图和无权图。带权图中,每条边都有一个代价或权重,代表两个节点之间的距离或代价。无权图中,每条边没有权重,代表两个节点之间的关系是相等的。

按照有无环,图可以分为有环图和无环图。有环图中,两个节点之间可以有多条路径;无环图中,两个节点之间最多只有一条路径。

图的表示方法

图可以使用多种方式进行表示,最常用的三种方式是邻接矩阵、邻接表和关联矩阵。

邻接矩阵

邻接矩阵是表示图的一种方法,它使用一个二维数组表示节点之间的连接关系。矩阵中的每个元素表示两个节点之间是否有连接,1表示有连接,0表示没有连接,如果是带权图,则可以将0表示为Infinity或-1。

[ [0, 1, 0, 1],[1, 0, 1, 0],[0, 1, 0, 1],[1, 0, 1, 0]
]

在上面的邻接矩阵中,行和列分别代表图中的节点,如果第i行第j列的元素为1,则表示节点i和节点j之间有一条边。如果是带权图,则可以在矩阵中存储边的权重。

邻接表

邻接表是表示图的一种方法,它使用链表的方式表示节点之间的连接关系。每个节点都有一个链表,链表中存储与该节点相邻的节点。

[[1, 3],[0, 2],[1, 3],[0, 2]
]

在上面的邻接表中,数组的下标代表节点的编号,数组元素是一个链表,该链表中存储与该节点相邻的节点的编号。如果是带权图,则链表中可以存储该边的权重。

关联矩阵

关联矩阵也是表示图的一种方法,它使用一个二维数组表示节点与边之间的关系。矩阵中的每个元素表示一个节点和一条边是否有连接关系。如果是带权图,则可以在矩阵中存储边的权重。

[[1, 0, 1, 0],[1, 1, 0, 0],[0, 1, 1, 1],[0, 0, 0, 1],[1, 1, 0, 1]
]

在上面的关联矩阵中,行和列分别代表图中的节点和边。如果第i行第j列的元素为1,则表示节点i和边j之间有连接。

图的遍历

图的遍历是指按照某种顺序来访问图中的所有节点,常用的遍历方法有深度优先遍历和广度优先遍历。

深度优先遍历

深度优先遍历从图中的一个节点开始,一直向下访问,直到没有未访问的节点为止,然后返回之前未访问过的节点,再依次访问。

const visited = [];
function depthFirstSearch(graph, node) {visited[node] = true;console.log(node);for (let i = 0; i < graph[node].length; i++) {const neighbor = graph[node][i];if (!visited[neighbor]) {depthFirstSearch(graph, neighbor);}}
}depthFirstSearch(graph, 0);

上面的代码是使用深度优先遍历来访问图中的节点,visited数组用于记录每个节点是否已经访问过,如果未访问过,则递归遍历该节点所连接的所有节点。

广度优先遍历

广度优先遍历从图中的一个节点开始,访问该节点的所有相邻节点,然后依次访问相邻节点的相邻节点,直到访问完所有节点为止。

function breadthFirstSearch(graph, startNode) {const visited = [];const queue = [];queue.push(startNode);visited[startNode] = true;while (queue.length) {const node = queue.shift();console.log(node);for (let i = 0; i < graph[node].length; i++) {const neighbor = graph[node][i];if (!visited[neighbor]) {visited[neighbor] = true;queue.push(neighbor);}}}
}breadthFirstSearch(graph, 0);

上面的代码是使用广度优先遍历来访问图中的节点,visited数组用于记录每个节点是否已经访问过,queue用于保存待访问的节点,先将起始节点入队,然后依次从队列中取出节点,将该节点的相邻节点入队。

图的常见算法

图是一个重要的数据结构,它有许多常见的算法,包括最短路径算法、拓扑排序算法、最小生成树算法等。

最短路径算法

最短路径算法用于求图中两个节点之间的最短路径,其中最常用的算法是Dijkstra算法和Bellman-Ford算法。

Dijkstra算法是一种贪心算法,它从起点向外扩展,每次找到当前距离最近的节点,并更新与之相邻节点的距离值,直到到达目标节点。

Bellman-Ford算法是一种动态规划算法,它从起点开始,依次更新到每个节点的距离值,循环执行N次,直到没有新的更新为止,其中N是图中节点的数量。它可以处理带有负权边的图,但是时间复杂度较高。

拓扑排序算法

拓扑排序算法用于对有向无环图进行排序,它可以用于任务调度、依赖关系分析等场景。

拓扑排序算法的基本思想

相关文章:

【JS常见数据结构】

JS数据结构 前言数组JavaScript 中数组的常见操作&#xff1a;1. 创建数组&#xff1a;2. 访问数组元素&#xff1a;3. 插入元素&#xff1a;4. 删除元素&#xff1a;5. 查询元素&#xff1a; 链表单向链表双向链表循环链表 栈队列树二叉树示例 图图的定义图的分类图的表示方法…...

算法基础之插入排序

1、插入排序基本思想 插入排序的工作原理是通过构建有序序列&#xff0c;对于未排序数据&#xff0c;在已排序序列中从后向前扫描&#xff0c;找到相应位置并插入。插入排序在实现上&#xff0c;通常采用in-place排序&#xff08;即只需用到O(1)的额外空间的排序&#xff09;&a…...

InfoQ 分享

...

Jupyter Notebook 遇上 NebulaGraph,可视化探索图数据库

在之前的《手把手教你用 NebulaGraph AI 全家桶跑图算法》中&#xff0c;除了介绍了 ngai 这个小工具之外&#xff0c;还提到了一件事有了 Jupyter Notebook 插件: https://github.com/wey-gu/ipython-ngql&#xff0c;可以更便捷地操作 NebulaGraph。 本文就手把手教你咋在 J…...

人类与机器的分类不同

分类能力也是智能的重要标识之一。通过分类&#xff0c;我们可以将事物或概念进行归类和组织&#xff0c;从而更好地理解和处理信息。分类在人类认知和智能发展中起到了重要的作用&#xff0c;它有助于我们对世界进行认知、记忆、推理和决策。在机器智能领域&#xff0c;分类同…...

WEB安全-SQL注入,CSRF跨站伪造,OXX跨站脚本

SQL 注入攻击 SQL 注入是一种网络攻击手段&#xff0c;攻击者通过在 Web 应用程序的输入字段中插入恶意 SQL 代码&#xff0c;试图访问、篡改或删除数据库中的数据。这种攻击通常发生在应用程序未对用户输入进行充分验证或过滤的情况下。 举个例子&#xff0c;例如&#xff0c;…...

【HDFS】客户端读某个块时,如何对块的各个副本进行网络距离排序?

本文包含如下内容: ① 通过图解+源码分析/A1/B1/node1和 /A1/B2/node2 这两个节点的网络距离怎么算出来的 ② 客户端读文件时,副本的优先级。(怎么排序的,排序规则都有哪些?) ③ 我们集群发现的一个问题。 客户端读时,通过调用getBlockLocations RPC 获取文件的各个块。…...

【数字化处理】仿生假体控制中肌电信号的数字化处理研究(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…...

谷歌推出Flax:JAX的神经网络库

在优化理论中&#xff0c;损失或成本函数测量拟合或预测值与实际值之间的距离。对于大多数机器学习模型&#xff0c;提高性能意味着最小化损失函数。 但对于深度神经网络&#xff0c;执行梯度下降以最小化每个参数的损失函数可能会消耗大量资源。传统方法包括手动推导和编码&a…...

PDF换行的难度,谁能解决?

换行的时候确认不了长度&#xff1a; import java.awt.*;public class Test {public static void main(String[] args) {String str1 "淘淘淘淘淘淘淘淘淘淘淘淘淘淘淘淘淘淘淘淘淘淘淘淘淘淘淘淘淘淘淘淘淘淘淘淘淘";String str2 "AAAAAAAAAAAAAAAAAAAAAAAAA…...

山东布谷科技直播程序源码使用Redis进行服务器横向扩展

当今&#xff0c;直播程序源码平台作为新媒体时代主流&#xff0c;受到了世界各地人民的喜爱&#xff0c;这也使得直播程序源码平台用户数量的庞大&#xff0c;也难免会出现大量用户同时访问服务器&#xff0c;使服务器过载的情况&#xff0c;当服务器承受不住的时候&#xff0…...

symfony3.4中根据角色不同跳转不同页面

在Symfony 3.4中&#xff0c;可以使用安全组件来实现控制不同角色跳转到不同页面的功能。 首先&#xff0c;确保你已经安装了Symfony的安全组件&#xff0c;并配置了安全相关的配置文件。这些文件通常是 security.yml 和 security.yml。 在配置文件中&#xff0c;你可以定义不…...

Dockerfile部署golang,docker-compose

使用go镜像打包&#xff0c;运行在容器内 redis和mysql用外部的 项目目录结构 w1go项目&#xff1a; Dockerfile # 这种方式是docker项目加上 本地的mysql和redis环境 # go打包的容器 FROM golang:alpine AS builder# 为我们镜像设置一些必要的环境变量 ENV GO111MODULEon …...

什么是Linux,如何在Windows操作系统下搭建Linux环境,远程连接Linux系统

文章目录 什么是LinuxLinux的诞生及发展为什么要学习LinuxLinux内核Linux发行版什么是虚拟机如何在VMware虚拟机中搭建Linux系统环境远程连接 Linux 系统Linux 帮助网站 什么是Linux Linux是一套免费使用和自由传播的类Unix操作系统&#xff0c;是一个基于POSIX和UNIX的多用户…...

Ubuntu下RabbitMQ安装与简单使用

一&#xff1a;RabbitMQ基本安装 1.更新依赖包(提前更新依赖包避免出现报错) sudo apt-get update 2.由于rabbitMq使用erlang语言开发&#xff0c;在安装rabbitMq之前需要安装erlang sudo apt-get install erlang 3.查看erlang是否安装成功 sudo erl 安装成功会出现下面的提示…...

力扣62.不同路径(动态规划)

/*** 一个机器人位于一个 m x n 网格的左上角 &#xff08;起始点在下图中标记为 “Start” &#xff09;。* 机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角&#xff08;在下图中标记为 “Finish” &#xff09;。* 问总共有多少条不同的路径&#xff1f; *…...

TypeScript 泛型的概念和基本使用

什么是TypeScript 泛型&#xff1f; 在定义函数&#xff0c;接口&#xff0c;类的时候不能预先确定使用的数据类型&#xff0c;而是在调用使用这些函数&#xff0c;接口&#xff0c;类的时候才能确定的数据类型&#xff1b; 1&#xff0c;单个泛型的参数 例如通过使用any这种…...

redis的事务和watch机制

这里写目录标题 第一章、redis事务和watch机制1.1&#xff09;redis事务&#xff0c;事务的三大命令语法&#xff1a;开启事务 multi语法&#xff1a;执行事务 exec语法&#xff1a;取消事务 discard 1.2&#xff09;redis事务的错误和回滚的情况1.3&#xff09;watch机制语法&…...

objectMapper.getTypeFactory().constructParametricType 方法的作用和使用

在使用 Jackson 库进行 JSON 数据的序列化和反序列化时&#xff0c;经常会使用到 ObjectMapper 类。其中&#xff0c;objectMapper.getTypeFactory().constructParametricType 方法用于构造泛型类型。 具体作用和使用如下&#xff1a; 作用&#xff1a; 构造泛型类型&#x…...

【websocket - Tornado】简易聊天应用

1、背景 项目测试的过程中需要自己搭建一个webscoket站点,确保此类服务接入后台系统后访问不受影响。python的服务框架常用的有Flask、Django、Tornado,每个框架的侧重点不同,导致使用的场景就会有所差异。 Flask轻量级,采用常规的同步编程方式,需要安装其他模块辅助,主…...

Python|GIF 解析与构建(5):手搓截屏和帧率控制

目录 Python&#xff5c;GIF 解析与构建&#xff08;5&#xff09;&#xff1a;手搓截屏和帧率控制 一、引言 二、技术实现&#xff1a;手搓截屏模块 2.1 核心原理 2.2 代码解析&#xff1a;ScreenshotData类 2.2.1 截图函数&#xff1a;capture_screen 三、技术实现&…...

Qt/C++开发监控GB28181系统/取流协议/同时支持udp/tcp被动/tcp主动

一、前言说明 在2011版本的gb28181协议中&#xff0c;拉取视频流只要求udp方式&#xff0c;从2016开始要求新增支持tcp被动和tcp主动两种方式&#xff0c;udp理论上会丢包的&#xff0c;所以实际使用过程可能会出现画面花屏的情况&#xff0c;而tcp肯定不丢包&#xff0c;起码…...

基于ASP.NET+ SQL Server实现(Web)医院信息管理系统

医院信息管理系统 1. 课程设计内容 在 visual studio 2017 平台上&#xff0c;开发一个“医院信息管理系统”Web 程序。 2. 课程设计目的 综合运用 c#.net 知识&#xff0c;在 vs 2017 平台上&#xff0c;进行 ASP.NET 应用程序和简易网站的开发&#xff1b;初步熟悉开发一…...

UE5 学习系列(三)创建和移动物体

这篇博客是该系列的第三篇&#xff0c;是在之前两篇博客的基础上展开&#xff0c;主要介绍如何在操作界面中创建和拖动物体&#xff0c;这篇博客跟随的视频链接如下&#xff1a; B 站视频&#xff1a;s03-创建和移动物体 如果你不打算开之前的博客并且对UE5 比较熟的话按照以…...

ElasticSearch搜索引擎之倒排索引及其底层算法

文章目录 一、搜索引擎1、什么是搜索引擎?2、搜索引擎的分类3、常用的搜索引擎4、搜索引擎的特点二、倒排索引1、简介2、为什么倒排索引不用B+树1.创建时间长,文件大。2.其次,树深,IO次数可怕。3.索引可能会失效。4.精准度差。三. 倒排索引四、算法1、Term Index的算法2、 …...

【C语言练习】080. 使用C语言实现简单的数据库操作

080. 使用C语言实现简单的数据库操作 080. 使用C语言实现简单的数据库操作使用原生APIODBC接口第三方库ORM框架文件模拟1. 安装SQLite2. 示例代码:使用SQLite创建数据库、表和插入数据3. 编译和运行4. 示例运行输出:5. 注意事项6. 总结080. 使用C语言实现简单的数据库操作 在…...

OPenCV CUDA模块图像处理-----对图像执行 均值漂移滤波(Mean Shift Filtering)函数meanShiftFiltering()

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 在 GPU 上对图像执行 均值漂移滤波&#xff08;Mean Shift Filtering&#xff09;&#xff0c;用于图像分割或平滑处理。 该函数将输入图像中的…...

[免费]微信小程序问卷调查系统(SpringBoot后端+Vue管理端)【论文+源码+SQL脚本】

大家好&#xff0c;我是java1234_小锋老师&#xff0c;看到一个不错的微信小程序问卷调查系统(SpringBoot后端Vue管理端)【论文源码SQL脚本】&#xff0c;分享下哈。 项目视频演示 【免费】微信小程序问卷调查系统(SpringBoot后端Vue管理端) Java毕业设计_哔哩哔哩_bilibili 项…...

基于Springboot+Vue的办公管理系统

角色&#xff1a; 管理员、员工 技术&#xff1a; 后端: SpringBoot, Vue2, MySQL, Mybatis-Plus 前端: Vue2, Element-UI, Axios, Echarts, Vue-Router 核心功能&#xff1a; 该办公管理系统是一个综合性的企业内部管理平台&#xff0c;旨在提升企业运营效率和员工管理水…...

【Android】Android 开发 ADB 常用指令

查看当前连接的设备 adb devices 连接设备 adb connect 设备IP 断开已连接的设备 adb disconnect 设备IP 安装应用 adb install 安装包的路径 卸载应用 adb uninstall 应用包名 查看已安装的应用包名 adb shell pm list packages 查看已安装的第三方应用包名 adb shell pm list…...