【数据结构】树的存储结构;树的遍历;哈夫曼树;并查集
欢~迎~光~临~^_^
目录
1、树的存储结构
1.1双亲表示法
1.2孩子表示法
1.3孩子兄弟表示法
2、树与二叉树的转换
3、树和森林的遍历
3.1树的遍历
3.1.1先根遍历
3.1.2后根遍历
3.2森林的遍历
3.2.1先序遍历森林
3.2.2中序遍历森林
4、树与二叉树的应用
4.1哈夫曼树
4.1.1概念
4.1.2构造哈夫曼树
4.1.3哈夫曼编码
4.1.4C语言实现哈夫曼树
4.2并查集编辑
4.2.1逻辑结构
4.2.2基本操作
4.2.3存储结构
4.2.4优化
1、树的存储结构
1.1双亲表示法
树的双亲表示法是一种简单的树结构表示方法,它在每个结点中存储了该结点的父节点信息。具体地,每个结点包含两部分信息,一部分是该结点的数据,另一部分是该结点的父节点的索引值。根结点没有父节点,通常用一个特定的值来表示。双亲表示法的优点是在访问任意结点的父节点时非常快,但是在查找任意结点的子节点时则需要遍历整棵树来确定其子节点。
例如,下面是一个有6个节点的树的双亲表示法的例子:
struct TreeNode {int data; // 节点数据int parent; // 父节点索引
};TreeNode tree[6]; // 定义一个有6个节点的树,每个节点包含数据和父节点索引两部分信息
tree[0].data = 1; // 第一个节点的数据是1,它是根节点,没有父节点
tree[1].data = 2; // 第二个节点的数据是2,它的父节点是根节点,其父节点索引为0
tree[1].parent = 0;
tree[2].data = 3; // 第三个节点的数据是3,它的父节点是根节点,其父节点索引为0
tree[2].parent = 0;
tree[3].data = 4; // 第四个节点的数据是4,它的父节点是第二个节点,其父节点索引为1
tree[3].parent = 1;
tree[4].data = 5; // 第五个节点的数据是5,它的父节点是第二个节点,其父节点索引为1
tree[4].parent = 1;
tree[5].data = 6; // 第六个节点的数据是6,它的父节点是第三个节点,其父节点索引为2
tree[5].parent = 2;
1.2孩子表示法
树的孩子表示法是一种常用的树的存储方式,它的基本思想是:每个节点都存储它的孩子节点的指针(地址)。
相比于其他树的存储方式,孩子表示法的优点是:
-
能够较快地访问节点的孩子节点,因为每个节点都存储了它的孩子节点的指针;
-
孩子表示法的存储方式相对简单、直观易懂。
但是,孩子表示法也存在一些缺点:
-
孩子节点的数量不固定,因此存储时需要动态分配内存空间;
-
访问父节点比较麻烦,需要从根节点开始遍历整棵树才能找到父节点。
1.3孩子兄弟表示法
孩子兄弟表示法是一种树型数据结构中用于表示节点关系的方法,通常用于表示一个树或者一棵森林中的节点之间的关系。
在孩子兄弟表示法中,每个节点包含两个指针:一个指向该节点的第一个孩子节点,另一个指向该节点的下一个兄弟节点。因此,通过这两个指针可以遍历整棵树或森林中的节点,并找到它们的父节点、孩子节点和兄弟节点。
孩子兄弟表示法的主要优点是它能够有效地减少存储空间的使用,因为每个节点只需要存储两个指针,而不需要像其他表示方法那样存储父节点和所有孩子节点的指针。
然而,由于每个节点只存储了两个指针,因此在进行某些操作时,可能需要遍历整棵树或森林,这可能会导致效率较低。
2、树与二叉树的转换
将一棵树转换为二叉树的方法,可以选择先把树转换为森林,然后再对每棵树进行转换。转换的基本思路是:将每个节点的第一个孩子作为其左孩子,将兄弟节点作为其右孩子。
具体实现如下:
1. 首先对树进行先序遍历,从根节点开始遍历。
2. 对于每个节点,如果它有孩子节点,将其第一个孩子节点作为其左孩子。
3. 对于每个节点的兄弟节点,将其作为当前节点右孩子。
4. 对于所有没有孩子节点的节点,将其左孩子和右孩子都设为空。
5. 最终得到的结果是一棵二叉树。
将一棵二叉树转换为一棵树的方法,可以选择先把二叉树转换为森林,然后再将森林中的所有树合并为一棵树。具体实现如下:
1. 针对每个节点,将其左孩子作为其第一个孩子节点,将其右孩子的子树转换为其兄弟节点。
2. 对于每个节点,先将其所有孩子节点合并为一棵子树,然后将其所有兄弟节点依次加入这棵子树中。
3. 最终得到的结果是一棵树。
3、树和森林的遍历
3.1树的遍历
3.1.1先根遍历
树的先根遍历是一种树的遍历方式,先访问根节点,然后依次遍历其子节点,再依次遍历每个子节点的子树的根节点。
例如,对于下图所示的树:
A/ \B C/ / \
D E F
先根遍历的顺序是:A -> B -> D -> C -> E -> F。
3.1.2后根遍历
树的后根遍历(也叫后序遍历)是指先访问一个节点的左子树和右子树,最后再访问该节点本身。具体的遍历顺序如下:
- 访问该节点的左子树
- 访问该节点的右子树
- 访问该节点本身
通常,可以使用递归或迭代算法实现树的后根遍历。递归的实现方式比较简单。
迭代的实现方式稍微复杂一些,需要借助栈来实现。具体的算法如下:
- 将根节点压入栈中
- 如果栈不为空,则取出栈顶节点
- 如果该节点没有左右子节点或者其左右子节点已经被访问过,则访问该节点并弹出
- 如果该节点有左右子节点且其左右子节点还未被访问,则将其右子节点和左子节点依次压入栈中,保证左右子节点先被访问
3.2森林的遍历
3.2.1先序遍历森林
先序遍历森林是指以任意一棵树的根节点为起点,按照先访问根节点,再依次访问子树的方式遍历整个森林。具体操作如下:
- 访问当前节点
- 依次以当前节点的子节点为根节点,重复进行上述操作
在实际操作中,可以采用递归或栈的方式实现先序遍历森林。以递归方式为例,实现代码如下:
void preOrderForest(Node* root) {if (root == nullptr) {return;}// 访问当前节点visit(root);// 依次遍历子树for (Node* child : root->children) {preOrderForest(child);}
}
其中,Node
代表树节点的数据结构,root
表示当前节点,children
表示当前节点的子节点列表,visit()
表示访问节点的操作。
3.2.2中序遍历森林
森林的后序遍历是将森林中每个树的后序遍历序列依次拼接起来,得到的序列即为森林的后序遍历。
具体步骤如下:
- 对每棵树分别进行后序遍历。
- 将每棵树的后序遍历序列依次拼接起来,即可得到森林的后序遍历序列。
例如,对以下森林进行后序遍历:
B C D/ \ / \
E F G H
首先分别对三棵树 B-EF、C、D-GH 进行后序遍历,得到它们的后序遍历序列:
B-EF的后序遍历序列为:E F B
C的后序遍历序列为:C
D-GH的后序遍历序列为:G H D
然后将它们依次拼接起来,得到森林的后序遍历序列:E F B C G H D
4、树与二叉树的应用
4.1哈夫曼树
4.1.1概念
哈夫曼树(Huffman Tree)是一种特殊的二叉树,它是一种最优二叉树,常用于数据压缩和编码中。哈夫曼树的构建过程是基于哈夫曼编码的原理,即将出现频率较高的字符用较短的编码,而出现频率较低的字符用较长的编码。哈夫曼树的构建过程是将每个字符作为一个节点,并将它们按照出现频率从小到大排序,然后将频率最小的两个节点合并成一个新的节点,其权值为两个节点的权值之和。重复这个过程,直到所有节点都被合并成为一个根节点为止。最后形成的这个根节点就是哈夫曼树的根节点。哈夫曼树的叶子节点表示原始数据中的字符,而路径上的0、1代表相应的比特位编码。哈夫曼树是一种满足最优化标准的树形结构,可以使编码后的数据更加紧凑,从而达到压缩数据的目的。
4.1.2构造哈夫曼树
哈夫曼树是一种带权路径长度最小的树,用于编码和数据压缩。构造哈夫曼树的过程如下:
- 将节点按权值从小到大排序,构造n个只含一个节点的二叉树,每个节点代表一个权值。
- 选择权值最小的两棵二叉树合并成一棵新二叉树,根节点的权值为这两棵二叉树的权值之和。
- 从已选的n棵二叉树中删除这两棵二叉树,将新的二叉树加入到集合中。
- 重复步骤2和步骤3,直到只剩下一棵二叉树,这棵树就是哈夫曼树。
4.1.3哈夫曼编码
将字符频次作为字符结点权值,构造哈夫曼树,即可得到哈夫曼编码,可用于数据压缩。
前缀编码:没有一个编码 是另一个编码的前缀
固定长度编码:每个字符用相等长度的二进制位表示
可变长度编码: 允许对不同字符用不等长的二进制位表示
哈夫曼编码的生成过程包括以下几个步骤:
- 统计每个字符在数据中出现的频率;
- 将每个字符和其对应的频率构建成一个叶子节点;
- 构建哈夫曼树,将每个节点按照频率从小到大排序,然后将相邻的两个节点合并成一个新节点,其频率为两个节点的频率之和。重复此过程,直到所有节点都合并为一个根节点;
- 给每个叶子节点分配一个编码,从根节点开始,向左走则编码为0,向右走则编码为1,直到到达叶子节点;
- 用每个字符的编码替换原始数据中相应的字符,从而得到压缩后的数据。
4.1.4C语言实现哈夫曼树
哈夫曼树是一种应用广泛的数据结构,用于有效地压缩数据。在C语言中,哈夫曼树的实现可以通过以下步骤完成:
1. 定义节点结构体
首先需要定义一个节点结构体,用于表示哈夫曼树中的每个节点。该结构体包含左子树、右子树、权值和字符等信息。
struct HuffmanNode {int weight; // 权值char ch; // 字符struct HuffmanNode *left; // 左子树struct HuffmanNode *right; // 右子树
};
2. 定义比较函数
比较函数用于在构建哈夫曼树时对节点进行排序。该函数将根据节点的权值大小进行比较。
int cmp(const void *a, const void *b) {const struct HuffmanNode *node1 = a;const struct HuffmanNode *node2 = b;return node1->weight - node2->weight;
}
3. 构建哈夫曼树
构建哈夫曼树的过程可以通过一些简单的步骤完成。首先需要将每个字符作为一个叶子节点插入到优先队列中,然后不断地取出队列中权值最小的两个节点,将它们合并成一个新节点,并将新节点插入到队列中。重复此过程,直到队列中只剩下一个根节点,此时构建的就是哈夫曼树。
struct HuffmanNode *buildHuffmanTree(const char *str) {// 统计字符出现的次数int count[256] = {0};for (int i = 0; i < strlen(str); i++) {count[str[i]]++;}// 将每个字符作为一个叶子节点插入到优先队列中int size = 0;struct HuffmanNode *nodes[256];for (int i = 0; i < 256; i++) {if (count[i] > 0) {nodes[size] = malloc(sizeof(struct HuffmanNode));nodes[size]->ch = (char)i;nodes[size]->weight = count[i];nodes[size]->left = NULL;nodes[size]->right = NULL;size++;}}// 构建哈夫曼树while (size > 1) {// 取出队列中权值最小的两个节点qsort(nodes, size, sizeof(struct HuffmanNode *), cmp);struct HuffmanNode *left = nodes[0];struct HuffmanNode *right = nodes[1];// 合并两个节点struct HuffmanNode *parent = malloc(sizeof(struct HuffmanNode));parent->ch = '\0';parent->weight = left->weight + right->weight;parent->left = left;parent->right = right;// 将新节点插入到队列中nodes[0] = parent;for (int i = 2; i < size; i++) {nodes[i - 1] = nodes[i];}size--;}return nodes[0];
}
4. 遍历哈夫曼树
遍历哈夫曼树可以得到每个字符的编码,即通过左子树走一步为0,右子树走一步为1。在遍历过程中,需要记录下从根节点到当前节点的路径上的字符编码,以便后续使用。
void traverseHuffmanTree(struct HuffmanNode *node, char *code, int depth) {if (node->left == NULL && node->right == NULL) {// 叶子节点,输出编码printf("%c: %s\n", node->ch, code);} else {// 遍历左子树code[depth] = '0';traverseHuffmanTree(node->left, code, depth + 1);// 遍历右子树code[depth] = '1';traverseHuffmanTree(node->right, code, depth + 1);}
}
5. 完整代码
将以上步骤整合起来,可以得到完整的C语言实现代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>struct HuffmanNode {int weight; // 权值char ch; // 字符struct HuffmanNode *left; // 左子树struct HuffmanNode *right; // 右子树
};int cmp(const void *a, const void *b) {const struct HuffmanNode *node1 = a;const struct HuffmanNode *node2 = b;return node1->weight - node2->weight;
}struct HuffmanNode *buildHuffmanTree(const char *str) {// 统计字符出现的次数int count[256] = {0};for (int i = 0; i < strlen(str); i++) {count[str[i]]++;}// 将每个字符作为一个叶子节点插入到优先队列中int size = 0;struct HuffmanNode *nodes[256];for (int i = 0; i < 256; i++) {if (count[i] > 0) {nodes[size] = malloc(sizeof(struct HuffmanNode));nodes[size]->ch = (char)i;nodes[size]->weight = count[i];nodes[size]->left = NULL;nodes[size]->right = NULL;size++;}}// 构建哈夫曼树while (size > 1) {// 取出队列中权值最小的两个节点qsort(nodes, size, sizeof(struct HuffmanNode *), cmp);struct HuffmanNode *left = nodes[0];struct HuffmanNode *right = nodes[1];// 合并两个节点struct HuffmanNode *parent = malloc(sizeof(struct HuffmanNode));parent->ch = '\0';parent->weight = left->weight + right->weight;parent->left = left;parent->right = right;// 将新节点插入到队列中nodes[0] = parent;for (int i = 2; i < size; i++) {nodes[i - 1] = nodes[i];}size--;}return nodes[0];
}void traverseHuffmanTree(struct HuffmanNode *node, char *code, int depth) {if (node->left == NULL && node->right == NULL) {// 叶子节点,输出编码printf("%c: %s\n", node->ch, code);} else {// 遍历左子树code[depth] = '0';traverseHuffmanTree(node->left, code, depth + 1);// 遍历右子树code[depth] = '1';traverseHuffmanTree(node->right, code, depth + 1);}
}int main() {char str[] = "hello world";struct HuffmanNode *root = buildHuffmanTree(str);char code[256];traverseHuffmanTree(root, code, 0);return 0;
}
4.2并查集
4.2.1逻辑结构
并查集是一种用于处理集合并、查找和判定两个元素是否在同一集合中的数据结构。它的基本操作有初始化、查找、合并等。
并查集的逻辑结构通常由一个数组和若干个操作函数构成。数组中每个元素对应一个集合,它的值表示当前元素所在集合的根节点编号。在初始化时,每个元素都是一个单独的集合,即它的根节点编号为自身。查找操作用于找到某个元素所在集合的根节点编号,它通过递归查找父节点的方式实现路径压缩。合并操作用于合并两个集合,它将其中一个集合的根节点编号设为另一个集合的根节点编号,从而实现两个集合的合并。
并查集的优点是可以快速地进行集合合并和查找,时间复杂度为O(log n)。它常用于解决连通性问题,如判断图是否连通、求无向图的连通分量等。
4.2.2基本操作
并查集是一种用于维护集合的数据结构,通常支持以下操作:
1. MakeSet(x):创建一个新的集合,其中只包含元素 x。
2. Union(x, y):将包含元素 x 和 y 的两个集合合并成一个新集合。
3. Find(x):查找元素 x 所在的集合,并返回该集合的代表元素。
通常还会有一些额外的操作,例如:
4. SizeOf(x):返回包含元素 x 的集合中元素的数量。
5. IsConnected(x, y):判断元素 x 和 y 是否在同一个集合中。
6. CountSets():返回当前并查集中集合的数量。
在实现并查集的过程中,常见的数据结构有数组和树。使用数组实现时,每个元素的值表示其父节点的索引,根节点的父节点值为-1。使用树实现时,每个节点的父节点指向它的父节点。
在 Find(x) 操作中,可以通过递归或迭代的方式将元素 x 所在的集合中的所有元素都指向该集合的代表元素,以达到路径压缩的效果,加快后续对同一集合的 Find 操作的速度。
在 Union(x, y) 操作中,可以选择将一个集合的根节点作为另一个集合的子树,或者将两个集合的根节点合并成一个新的集合。通常建议采用按秩合并和路径压缩(即将深度较浅的树作为深度较深的树的子树)的算法,以保证并查集操作的时间复杂度为 O(α(n)),其中 α(n) 是反阿克曼函数的逆函数,增长极其缓慢,因此在实际应用中可以认为它是一个常数。
4.2.3存储结构
并查集的存储结构可以采用数组或树形结构。常用的是采用树形结构进行存储。
对于每个元素x,都有一个对应的父结点parent[x],如果x是根结点,则parent[x]=-1。在初始化时,可以将每个元素看成一个独立的集合,即其父节点为其自身。随着不断的合并操作,两个元素所在的集合就会合并成为一棵树。
在合并两个集合时,需要将其中一个集合的根节点的父结点设置为另一个集合的根节点。此时,其中一个树就成为另一个树的子树。
通过路径压缩的技巧,可以使得树形结构更加扁平化,从而提高查询效率。具体而言,在查找某个元素所在的集合时,可以沿途将路径上的节点的父节点都设置为该集合的根节点,从而将树的高度降低,进一步提高查询效率。
4.2.4优化
并查集是一种数据结构,用于解决集合的合并和查询问题。在对大量数据进行操作时,为了提高效率,需要对并查集进行优化。
以下是一些并查集的优化方法:
1. 路径压缩:在 find 操作时,将路径上的所有节点都直接连接到根节点上,从而缩短查找路径的长度,减少操作的时间复杂度。
2. 按秩合并:在合并两个集合时,将高度低的集合合并到高度高的集合中,从而保持树的平衡,减少操作的时间复杂度。
3. 路径分裂:在路径压缩时,不仅将路径上的所有节点直接连接到根节点上,还可以将路径上的每个节点的父节点指向其祖先节点的子节点,从而减少路径压缩导致的树的深度增加。
4. 路径减半:在路径压缩时,不仅将路径上的所有节点直接连接到根节点上,还可以将路径上每隔一个节点的父节点指向其祖先节点的父节点,从而减少路径压缩导致的树的深度增加。
🤞❤️🤞❤️🤞❤️树与二叉树的知识点总结就到这里啦,如果对博文还满意的话,劳烦各位看官动动“发财的小手”留下您对博文的赞和对博主的关注吧🤞❤️🤞❤️🤞❤️
相关文章:
【数据结构】树的存储结构;树的遍历;哈夫曼树;并查集
欢~迎~光~临~^_^ 目录 1、树的存储结构 1.1双亲表示法 1.2孩子表示法 1.3孩子兄弟表示法 2、树与二叉树的转换 3、树和森林的遍历 3.1树的遍历 3.1.1先根遍历 3.1.2后根遍历 3.2森林的遍历 3.2.1先序遍历森林 3.2.2中序遍历森林 4、树与二叉树的应用 4.1哈夫曼树…...
CSS选择器练习小游戏
请结合CSS选择器练习小游戏进行阅读(网页的动态效果是没有办法通过静态图片展示的) 网址:请点击 有些题有多种答案,本文就不一一列出了 第一题 答案:plate第二题 答案:bento第三题 答案:#fa…...
Python运算符、函数与模块和程序控制结构
给我家憨憨写的python教程 ——雁丘 Python运算符、函数与模块和程序控制结构 关于本专栏一 运算符1.1 位运算符1.1.1 按位取反1.1.2 按位与1.1.3 按位或1.1.4 按位异或1.1.5 左移位 1.2 关系运算符1.3 运算顺序1.4 运算方向 二 函数与模块2.1 内建函数2.2 库函数2.2.1 标准库…...
微服务保护-Sentinel
初识Sentinel 雪崩问题及解决方案 雪崩问题 微服务中,服务间调用关系错综复杂,一个微服务往往依赖于多个其它微服务。 如图,如果服务提供者I发生了故障,当前的应用的部分业务因为依赖于服务I,因此也会被阻塞。此时&a…...
Doris 导出表结构或数据
MYSQLDUMP 导出表结构或数据 Doris 在0.15 之后的版本已经支持通过mysqldump 工具导出数据或者表结构 使用示例 导出 导出 test 数据库中的 table1 表:mysqldump -h127.0.0.1 -P9030 -uroot --no-tablespaces --databases test --tables table1导出 test 数…...
SELECT * from t_user where user_id = xxx,可以从那几个点去优化这句sql
优化SQL查询可以从以下几个方面入手: 1. 索引优化:通过为查询涉及的列添加合适的索引,可以提高查询的效率。在该SQL语句中, user_id 列被用作查询条件,可以为 user_id 列创建一个索引。 2. 避免使用 SELECT *…...
解决报错 java.lang.IllegalArgumentException: Cannot format given Object as a Date
报错原因:我们在SimpleDateFormat.format转化时间格式的时候,传入的值无法转换成date而报的错 我的代码大概就是下面这种 LocalDate now LocalDate.now();String format1 new SimpleDateFormat("yyyy-MM-dd").format(now); 发现SimpleDateF…...
【Git】03-GitHub
文章目录 1. GitHub核心功能2. GitHub搜索项目3. GitHub搭建个人博客4. 团队项目创建5. git工作流选择5.1 需要考虑的因素5.2 主干开发5.2 Git Flow5.3 GitHub Flow5.4 GitLab Flow(带生产分支)5.4 GitLab Flow(带环境分支)5.4 GitLab Flow(带发布分支) 6. 分支集成策略7. 启用…...
Java手写最短路径算法和案例拓展
Java手写最短路径算法和案例拓展 1. 算法手写的必要性 在实际开发中,经常需要处理图的最短路径问题。虽然Java提供了一些图算法库,但手写最短路径算法的必要性体现在以下几个方面: 理解算法原理:手写算法可以帮助我们深入理解最…...
深度学习实战51-基于Stable Diffusion模型的图像生成原理详解与项目实战
大家好,我是微学AI,今天给大家介绍一下深度学习实战51-基于Stable Diffusion模型的图像生成原理详解与项目实战。大家知道现在各个平台发的漂亮小姐姐,漂亮的图片是怎么生成的吗?这些生成的底层原理就是用到了Stable Diffusion模型。Stable Diffusion是一种基于深度学习的图…...
基于matlab实现的多普勒脉冲雷达回波仿真
完整程序: clear all;clc;close all; fc3e9; %载波频率 PRF2000; Br5e6; %带宽 fs10*Br; %采样频率 Tp5e-6; %脉宽 KrBr/Tp; %频率变化率 c3e8; %光速 lamda…...
Linux服务器中安装Anaconda+Tensorflow+Keras
Anaconda安装 从https://repo.anaconda.com/archive/查看你需要下载的Anaconda版本,例如2020.11的x86_64(uname -a 查看linux框架)版下载Anaconda到linux服务器, wget https://repo.anaconda.com/archive/Anaconda3-2020.11-Li…...
ubuntu+.net6+docker 应用部署教程
先期工作 1、本地首先安装 Docker Desktop 2、本地装linux in windows 3、生成镜像 后期工作 1、云服务器部署 生成镜像方法 1、生成Dockerfile配置文件 开发工具visual studio 2022 如果项目已经存在,可以选中项目,右键点击->选择添加Docker…...
Spring常见面试题总结
什么是Spring Spring是一个轻量级Java开发框架,目的是为了解决企业级应用开发的业务逻辑层和其他各层的耦合问题,以提高开发效率。它是一个分层的JavaSE/JavaEE full-stack(一站式)轻量级开源框架,为开发Java应用程序…...
Git全套命令使用
日升时奋斗,日落时自省 目录 1、Git安装 1.1、创建git本地仓库 1.2、配置Git 1.3、认识Git内部区分 2、Git应用操作 2.1、添加文件 2.2、查看日志 2.3、查看修改信息 2.4、查看添加信息 3、版本回退 4、撤销修改 4.1、工作区撤销 4.2、已经add…...
【陕西理工大学-数学软件实训】数学实验报告(8)(数值微积分与方程数值求解)
目录 一、实验目的 二、实验要求 三、实验内容与结果 四、实验心得 一、实验目的 1. 掌握求数值导数和数值积分的方法。 2. 掌握代数方程数值求解的方法。 3. 掌握常微分方程数值求解的方法。 二、实验要求 1. 根据实验内容,编写相应的MATLAB程序,…...
Vue3为什么推荐使用ref而不是reactive
为什么推荐使用ref而不是reactive reactive本身具有很大局限性导致使用过程需要额外注意,如果忽视这些问题将对开发造成不小的麻烦;ref更像是vue2时代option api的data的替代,可以存放任何数据类型,而reactive声明的数据类型只能是对象; 先抛出结论,再详细说原因:非必要不用rea…...
JavaScript函数this指向
一、this的指向规则 1.this到底指向什么呢? 我们先来看一个让人困惑的问题: 定义一个函数,我们采用三种不同的方式对它进行调用,它产生了三种不同的结果 // 定义函数 function foo(name) {console.log("foo函数:", …...
Java的序列化
写在前面 本文看下序列化和反序列化相关的内容。 源码 。 1:为什么,什么是序列化和反序列化 Java对象是在jvm的堆中的,而堆其实就是一块内存,如果jvm重启数据将会丢失,当我们希望jvm重启也不要丢失某些对象ÿ…...
计算机二级python简单应用题刷题笔记(一)
计算机二级python简单应用题刷题笔记(一) 1、词频统计:键盘输入一组我国高校所对应的学校类型,以空格分隔,共一行。2、找最大值、最小值、平均分:键盘输入小明学习的课程名称及考分等信息,信息间…...
Spring注解家族介绍: @RequestMapping
前言: 今天我们来介绍RequestMapping这个注解,这个注解的内容相对来讲比较少,篇幅会比较短。 目录 前言: RequestMapping 应用场景: 总结: RequestMapping RequestMapping 是一个用于映射 HTTP 请求…...
系统架构设计师(第二版)学习笔记----信息安全系统及信息安全技术
【原文链接】系统架构设计师(第二版)学习笔记----信息加解密技术 文章目录 一、信息安全系统的组成框架1.1 信息安全系统组成框架1.2 信息安全系统技术内容1.3 常用的基础安全设备1.4 网络安全技术内容1.5 操作系统安全内容1.6 操作系统安全机制1.7 数据…...
交换机的工作原理(含实例,华为ensp操作)
目录 1.交换机学习和转发 案例 1.设置静态地址表项 2.配置黑洞mac地址表项 1.交换机学习和转发 交换机工作在数据链路层。当交换机从某个端口收到一个帧时,它并不是向所有的接口转发此帧,而是根据此帧的目的MAC地址&a…...
从字符串中删除指定字符
任务描述 编写一个函数实现功能:从字符串中删除指定的字符。同一字母的大、小写按不同字符处理。例如:程序执行时输入字符串:turbo c and Borland c,从键盘输入字符n,则输出后变为:turbo c ad Borlad c。如…...
Xcode14.3.1 真机调试iOS17的方法(无iOS17 DeviceSupport)
由于iOS17需要使用Xcode15 才能调试,而当前Xcode15都是beta,正式版还未出,那么要真机调试iOS17的方式一般有两种: 方法一: 一种是下载新的Xcode15 beta版 (但Xcode包一般比较大,好几个G&#…...
JWT基础
概念 JSON Web Token本质上就是一串字符串,一串包含了很多信息的字符串令牌拥有三个部分头部-包含加密算法和令牌类型{"alg":"算法名称","type":"JWT"}负载-包含数据和信息-七个官方默认-也可以自己定义内容{issÿ…...
关于远程工作的面试可能存在的陷阱
附上看到的完整帖子地址:面试 POPER 的后端开发工程师的离奇经历 分享一下我遇到过的,我至少面试过10个远程工作,其中有3个的面试是直接让我完成一个需求的,前两次都耐心做了,第3次看到相同要求时我都懒得回复了&…...
Qt5开发及实例V2.0-第一章Qt概述
Qt5开发及实例V2.0-第一章-Qt概述 第一章-Qt概述1.1 什么是Qt1.2 Qt 5的安装1.2.1 下载安装Qt 51.2.2 运行Qt 5 Creator1.2.3 Qt 5开发环境 1.3 Qt 5开发步骤及实例1.3.1 设计器Qt 5 Designer实现1.3.2 代码实现简单实例 L1.2 Qt 5安装:概念解析L1.3 Qt 5开发步骤及…...
matlab检索相似图像
在Matlab中检索相似图像通常需要使用图像处理和计算机视觉技术。以下是一种常见的方法,可以帮助您在Matlab中进行相似图像检索: 准备图像数据库: 首先,您需要有一个包含待检索图像的图像数据库。这些图像应该经过预处理࿰…...
ArrayBlockingQueue 带有三个参数的构造函数为何需要加锁?
哪一个构造函数 public ArrayBlockingQueue(int capacity, boolean fair,Collection<? extends E> c) {this(capacity, fair);final ReentrantLock lock = this.lock;lock.lock(); // Lock only for visibility, not mutual exclusiontry {final Object[] items = this…...
自己的公众号/企业seo顾问服务
错误原因:端口号冲突或者被占用: 解决办法:停掉正占用端口号的服务,或者在tomcat的config下配置port端口号新的名字 详细解决为: 2.启动报错: 1.暴力:找到占用的端口号并找到对应的进程,并杀死该进程|netstat -ano 找到端口对应的 PI…...
外贸网站建设公司案例/18款禁用看奶app入口
思路: 这题应该不止一种解法,其中的一种可以看作是leetcode85https://www.cnblogs.com/wangyiming/p/11059176.html的加强版: 首先对于每一行,分别使用滑动窗口法将这一行划分成符合题目定义的若干合法子段s1, s2, s3, ...。对于每…...
番禺做网站的/个人网站模板免费下载
大家好,我是为人造的智能操碎了心的智能禅师。尽听说现在国内外一线互联网巨头,包括后起的独角兽,对 AI 人才的需求非常大,Google、Facebook 为了抢 AI 人才都快 battle 起来了。然而实际上,AI 岗位还是面临僧多粥少的…...
杰讯山西网站建设/seo什么意思简单来说
display布局中有两个属性,一个是none可以使其修饰的标签隐藏,show可以使其修饰的标签显示出来...
企业网站开发教程/seo全称英文怎么说
两个docker容器 docker run -it -d --link onlinedb:onlinedb --name app -p 8066:8080 onlineexam/app:v1.0 需要加--link 容器名:别名 其中的别名要放到url中 另外application.properties中url需设置为: spring.datasource.urljdbc:mysql://onl…...
最好的网站建设价格/2022年国际十大新闻
Demo: ma125120.github.io/ma-dom/test… 本方法主要使用了 Range 对象和HTML5的Selection API,经过测试,本方法在主流浏览器如谷歌浏览器、火狐浏览器、360安全浏览器、搜狗高速浏览器中均运行良好。 先附上大家最想看的代码: function copy…...