【蓝桥杯软件赛 零基础备赛20周】第7周——二叉树

文章目录

  • 1 二叉树概念
  • 2 二叉树的存储和编码
    • 2.1 二叉树的存储方法
    • 2.2 二叉树存储的编码实现
    • 2.3 二叉树的极简存储方法
  • 3 例题
  • 4 习题

前面介绍的数据结构数组、队列、栈,都是线性的,它们存储数据的方式是把相同类型的数据按顺序一个接一个串在一起。简单的形态使线性表难以实现高效率的操作。

二叉树是一种层次化的、高度组织性的数据结构。二叉树的形态使得它有天然的优势,在二叉树上做查询、插入、删除、修改、区间等操作极为高效,基于二叉树的算法也很容易实现高效率的计算。

1 二叉树概念

二叉树的每个节点最多有两个子节点,分别称为左孩子、右孩子,以它们为根的子树称为左子树、右子树。二叉树的每一层以2的倍数递增,所以二叉树的第k层最多有 2 k − 1 2^{k-1} 2k1 个节点。根据每一层的节点分布情况,有以下常见的二叉树。

(1)满二叉树

特征是每一层的节点数都是满的。第一层只有1个节点,编号为1;第二层有2个节点,编号2、3;第三层有4个节点,编号4、5、6、7;…;第k层有 2 k − 1 2^{k-1} 2k1 个节点,编号 2 k − 1 2^{k-1} 2k1 2 k − 1 + 1 2^{k-1}+1 2k1+1、…、 2 k − 1 2^k-1 2k1

一棵n层的满二叉树,节点一共有 1 + 2 + 4 + . . . + 2 n − 1 = 2 n − 1 1+2+4+...+2^{n-1} = 2^{n-1} 1+2+4+...+2n1=2n1 个。

在这里插入图片描述

(2)完全二叉树

如果满二叉树只在最后一层有缺失,并且缺失的节点都在最后,称为完全二叉树。上图演示了一棵满二叉树和一棵完全二叉树。

(3)平衡二叉树

任意左子树和右子树的高度差不大于1,称为平衡二叉树。若只有少部分子树的高度差超过1,这是一棵接近平衡的二叉树。

在这里插入图片描述

(4)退化二叉树

如果树上每个节点都只有1个孩子,称为退化二叉树。退化二叉树实际上已经变成了一根链表。如果绝大部分节点只有1个孩子,少数有2个孩子,也看成退化二叉树。

二叉树之所以应用广泛,得益于它的形态。高级数据结构大部分和二叉树有关,下面列举二叉树的一些优势。

(1)在二叉树上能进行极高效率的访问。一棵平衡的二叉树,例如满二叉树或完全二叉树,每一层的节点数量约是上一层数量的2倍,也就是说,一棵有N个节点的满二叉树,树的高度是O(logN)。从根节点到叶子节点,只需要走logN步,例如N = 100万,树的高度仅有logN = 20,只需要20步就能到达100万个节点中的任意一个。但是,如果二叉树不是满的,而且很不平衡,甚至在极端情况下变成退化二叉树,访问效率会打折扣。维护二叉树的平衡是高级数据结构的主要任务之一。

(2)二叉树很适合做从整体到局部、从局部到整体的操作。二叉树内的一棵子树可以看成整棵树的一个子区间,求区间最值、区间和、区间翻转、区间合并、区间分裂等,用二叉树都很快捷。

(3)基于二叉树的算法容易设计和实现。例如二叉树用BFS和DFS搜索处理都极为简便。二叉树可以一层一层地搜索,这是BFS。二叉树的任意一个子节点,是以它为根的一棵二叉树,这是一种递归的结构,用DFS访问二叉树极容易编码。

2 二叉树的存储和编码

2.1 二叉树的存储方法

要使用二叉树,首先得定义和存储它的节点。

二叉树的一个节点包括三个值:节点的值、指向左孩子的指针、指向右孩子的指针。需要用一个结构体来定义二叉树。

二叉树的节点有动态和静态两种存储方法,竞赛中一般采用静态方法。

(1)动态存储二叉树。例如写c代码,数据结构的教科书一般这样定义二叉树的节点:

struct Node{int value;           //节点的值,可以定义多个值Node *lson, *rson;   //指针,分别指向左右子节点    
};

其中value是这个节点的值,lson和rson是指向两个孩子的指针。动态新建一个Node时,用new运算符动态申请一个节点。使用完毕后,需要用delete释放它,否则会内存泄漏。动态二叉树的优点是不浪费空间,缺点是需要管理,不小心会出错,竞赛中一般不这样用。

(2)用静态数组存储二叉树。在算法竞赛中,为了编码简单,加快速度,一般用静态数组来实现二叉树。下面定义一个大小为N的结构体数组。N的值根据题目要求设定,有时节点多,例如N=100万,那么tree[N]使用的内存是12M字节,不算大。

struct Node{                //静态二叉树int value;               //可以把value简写为vint lson, rson;          //左右孩子,可以把lson、rson简写为ls、rs
}tree[N];                   //可以把tree简写为t

tree[i]表示这个节点存储在结构体数组的第i个位置,lson是它的左孩子在结构体数组的位置,rson是它的右孩子在结构体数组的位置。lson和rson指向孩子的位置,也可以称为指针。

下图演示了一棵二叉树的存储,圆圈内的字母是这个节点的value值。根节点存储在tree[5]上,它的左孩子lson=7,表示左孩子存储在tree[7]上,右孩子rson=3,存储在tree[3]。
在这里插入图片描述

编码时一般不用tree[0],因为0常常被用来表示空节点,例如叶子节点tree[2]没有子节点,就把它的子节点赋值为lson = rson = 0。

2.2 二叉树存储的编码实现

下面写代码演示上图中二叉树的建立,并输出二叉树。

(1)C++代码。第16~21行建立二叉树,然后用print_tree()输出二叉树。

#include <bits/stdc++.h>
using namespace std;
const int N=100;               //注意const不能少
struct Node{                   //定义静态二叉树结构体char v;                     //把value简写为vint ls, rs;                 //左右孩子,把lson、rson简写为ls、rs
}t[N];                         //把tree简写为t
void print_tree(int u){        //打印二叉树if(u){cout<<t[u].v<<' ';     //打印节点u的值print_tree(t[u].ls);   //继续搜左孩子print_tree(t[u].rs);   //继续搜右孩子}
}
int main(){t[5].v='A'; t[5].ls=7; t[5].rs=3;t[7].v='B'; t[7].ls=2; t[7].rs=0;t[3].v='C'; t[3].ls=9; t[3].rs=6;t[2].v='D';    // t[2].ls=0; t[2].rs=0; 可以不写,因为t[]是全局变量,已初始化为0t[9].v='E';    // t[9].ls=0; t[9].rs=0; 可以不写t[6].v='F';    // t[6].ls=0; t[6].rs=0; 可以不写int root = 5;  //根是tree[5]print_tree(5); //输出: A B D C E Freturn 0;
}

初学者可能看不懂print_tree()是怎么工作的。它是一个递归函数,先打印这个节点的值t[u].v,然后继续搜它的左右孩子。上图的打印结果是”A B D C E F”,步骤如下:
  
  (1)首先打印根节点A;
  (2)然后搜左孩子,是B,打印出来;
  (3)继续搜B的左孩子,是D,打印出来;
  (4)D没有孩子,回到B,B发现也没有右孩子,继续回到A;
  (5)A有右孩子C,打印出来;
  (6)打印C的左右孩子E、F。

这个递归函数执行的步骤称为“先序遍历”,先输出父节点,然后再搜左右孩子并输出。还有“中序遍历”和“后序遍历”,将在后面讲解。

(2)Java代码

import java.util.*;
class Main {static class Node {char v;int ls, rs;}static final int N = 100;static Node[] t = new Node[N];static void print_tree(int u) {if (u != 0) {System.out.print(t[u].v + " ");print_tree(t[u].ls);print_tree(t[u].rs);}}public static void main(String[] args) {t[5] = new Node(); t[5].v = 'A'; t[5].ls = 7; t[5].rs = 3;t[7] = new Node(); t[7].v = 'B'; t[7].ls = 2; t[7].rs = 0;t[3] = new Node(); t[3].v = 'C'; t[3].ls = 9; t[3].rs = 6;t[2] = new Node(); t[2].v = 'D';t[9] = new Node(); t[9].v = 'E';t[6] = new Node(); t[6].v = 'F';int root = 5;print_tree(5); // 输出: A B D C E F}
}

(3)Python代码

N = 100
class Node:   # 定义静态二叉树结构体def __init__(self):self.v = ''              # 把value简写为vself.ls = 0              # 左右孩子,把lson、rson简写为ls、rsself.rs = 0
t = [Node() for i in range(N)]   # 把tree简写为t
def print_tree(u):if u:print(t[u].v, end=' ')   # 打印节点u的值print_tree(t[u].ls)print_tree(t[u].rs)
t[5].v, t[5].ls, t[5].rs = 'A', 7, 3
t[7].v, t[7].ls, t[7].rs = 'B', 2, 0
t[3].v, t[3].ls, t[3].rs = 'C', 9, 6
t[2].v = 'D'    # t[2].ls=0; t[2].rs=0; 可以不写,因为t[]已初始化为0
t[9].v = 'E'    # t[9].ls=0; t[9].rs=0; 可以不写
t[6].v = 'F'    # t[6].ls=0; t[6].rs=0; 可以不写
root = 5        # 根是tree[5]
print_tree(5)   # 输出: A B D C E F

2.3 二叉树的极简存储方法

如果是满二叉树或者完全二叉树,有更简单的编码方法,连lson、rson都不需要定义,因为可以用数组的下标定位左右孩子。

一棵节点总数量为k的完全二叉树,设1号点为根节点,有以下性质:

(1) p > 1 p > 1 p>1的节点,其父节点是 ⌊ p / 2 ⌋ \lfloor p/2 \rfloor p/2。例如 p = 4 p=4 p=4,父亲是 4 / 2 = 2 4/2=2 4/2=2 p = 5 p=5 p=5,父亲是 5 / 2 = 2 5/2=2 5/2=2
(2)如果 2 × p > k 2×p> k 2×p>k,那么 p p p没有孩子;如果 2 × p + 1 > k 2×p+1 > k 2×p+1>k,那么 p p p没有右孩子。例如 k = 11 k=11 k=11 p = 6 p=6 p=6的节点没有孩子; k = 12 k=12 k=12 p = 6 p=6 p=6的节点没有右孩子。
(3)如果节点 p p p有孩子,那么它的左孩子是 2 × p 2×p 2×p,右孩子是 2 × p + 1 2×p+1 2×p+1
在这里插入图片描述

图中圆圈内是节点的值,圆圈外数字是节点存储位置。

(1)C++代码。

l s ( p ) ls(p) ls(p)找p的左孩子,用 r s ( p ) rs(p) rs(p)找p的右孩子。 l s ( p ) ls(p) ls(p)中把 p ∗ 2 p*2 p2写成 p < < 1 p<<1 p<<1,用了位运算。

#include <bits/stdc++.h>
using namespace std;
const int N=100;                   //注意const不能少
char t[N];                         //简单地用一个数组定义二叉树
int ls(int p){return p<<1;}        //定位左孩子,也可以写成 p*2
int rs(int p){return p<<1 | 1;}    //定位右孩子,也可以写成 p*2+1
int main(){t[1]='A';  t[2]='B';  t[3]='C';t[4]='D';  t[5]='E';  t[6]='F';  t[7]='G';t[8]='H';  t[9]='I';  t[10]='J'; t[11]='K';cout<<t[1]<<":lson="<<t[ls(1)]<<" rson="<<t[rs(1)]; //输出  A:lson=B rson=Ccout<<endl;cout<<t[5]<<":lson="<<t[ls(5)]<<" rson="<<t[rs(5)]; //输出  E:lson=J rson=Kreturn 0;
}

(2)Java代码。

import java.util.Arrays;
public class Main {static int ls(int p){ return p<<1;}static int rs(int p){ return p<<1 | 1;}public static void main(String[] args) {final int N = 100;char[] t = new char[N];t[1]='A';  t[2]='B';  t[3]='C';t[4]='D';  t[5]='E';  t[6]='F';  t[7]='G';t[8]='H';  t[9]='I';  t[10]='J'; t[11]='K';System.out.print(t[1]+":lson="+t[ls(1)]+" rson="+t[rs(1)]);//输出A:lson=B rson=CSystem.out.println();System.out.print(t[5]+":lson="+t[ls(5)]+" rson="+t[rs(5)]);//输出E:lson=J rson=K}
}

(3)Python代码。

N = 100
t = [''] * N
def ls(p):  return p << 1
def rs(p):  return (p << 1) | 1t[1] = 'A'; t[2] = 'B'; t[3] = 'C'
t[4] = 'D'; t[5] = 'E'; t[6] = 'F'; t[7] = 'G'
t[8] = 'H'; t[9] = 'I'; t[10] = 'J'; t[11] = 'K'print(t[1] + ':lson=' + t[ls(1)] + ' rson=' + t[rs(1)]) # 输出  A:lson=B rson=C
print(t[5] + ':lson=' + t[ls(5)] + ' rson=' + t[rs(5)]) # 输出  E:lson=J rson=K

其实,即使二叉树不是完全二叉树,而是普通二叉树,也可以用这种简单方法来存储。如果某个节点没有值,那就空着这个节点不用,方法是把它赋值为一个不该出现的值,例如赋值为0或无穷大INF。这样会浪费一些空间,好处是编程非常简单。

3 例题

二叉树是很基本的数据结构,大量算法、高级数据结构都是基于二叉树的。二叉树有很多操作,最基础的操作是搜索(遍历)二叉树的每个节点,有先序遍历、中序遍历、后序遍历。这3种遍历都用到了递归函数,二叉树的形态天然适合用递归来编程。
在这里插入图片描述

(1)先(父)序遍历,父节点在最前面输出。先输出父节点,再访问左孩子,最后访问右孩子。上图的先序遍历结果是ABDCEF。为什么?把结果分解为:A-BD-CEF。父亲是A,然后是左孩子B和它带领的子树BD,最后是右孩子C和它带领的子树CEF。这是一个递归的过程,每个子树也满足先序遍历,例如CEF,父亲是C,然后是左孩子E,最后是右孩子F。

(2)中(父)序遍历,父节点在中间输出。先访问左孩子,然后输出父节点,最后访问右孩子。上图的中序遍历结果是DBAECF。为什么?把结果分解为:DB-A-ECF。DB是左子树,然后是父亲A,最后是右子树ECF。每个子树也满足中序遍历,例如ECF,先左孩子E,然后是父亲C,最后是右孩子F。

(3)后(父)序遍历,父节点在最后输出。先访问左孩子,然后访问右孩子,最后输出父节点。上图的后序遍历结果是DBEFCA。为什么?把结果分解为:DB-EFC-A。DB是左子树,然后是右子树EFC,最后是父亲A。每个子树也满足后序遍历,例如EFC,先左孩子E,然后是右孩子F,最后是父亲C。

这三种遍历,中序遍历是最有用的,它是二叉查找树的核心。

例题 二叉树的遍历

(1)C++代码

#include <bits/stdc++.h>
using namespace std;
const int N = 100005;
struct Node{int v; int ls, rs;
}t[N];                          //tree[0]不用,0表示空结点
void preorder (int p){          //求先序序列if(p != 0){cout << t[p].v <<" ";   //先序输出preorder (t[p].ls);preorder (t[p].rs);}
}
void midorder (int p){          //求中序序列if(p != 0){midorder (t[p].ls);cout << t[p].v <<" ";   //中序输出midorder (t[p].rs);}
}
void postorder (int p){         //求后序序列if(p != 0){postorder (t[p].ls);postorder (t[p].rs);cout << t[p].v <<" ";    //后序输出}
}
int main() {int n;	cin >> n;for (int i = 1; i <= n; i++) {int a, b; cin >> a >> b;t[i].v = i;t[i].ls = a;t[i].rs = b;}preorder(1);  cout << endl;midorder(1);  cout << endl;postorder(1); cout << endl;
}

(2)Java代码

下面的Java代码和上面的C++代码略有不同。例如在preorder()中没有直接打印节点的值,而是用joiner.add()先记录下来,遍历结束后一起打印,这样快一些。本题 n = 1 0 6 n=10^6 n=106 ,规模大,时间紧张。

import java.util.Scanner;
import java.util.StringJoiner;
class Main {static class Node {int v, ls, rs;Node(int v, int ls, int rs) {this.v = v;this.ls = ls;this.rs = rs;}}static final int N = 100005;static Node[] t = new Node[N];                     //tree[0]不用,0表示空结点static void preorder(int p, StringJoiner joiner) { //求先序序列if (p != 0) {joiner.add(t[p].v + "");   //不是直接打印,而是先记录下来preorder(t[p].ls,joiner);preorder(t[p].rs,joiner);}}static void midorder(int p, StringJoiner joiner) { //求中序序列if (p != 0) {midorder(t[p].ls,joiner);joiner.add(t[p].v + "");//中序输出midorder(t[p].rs,joiner);}}static void postorder(int p, StringJoiner joiner) { //求后序序列if (p != 0) {postorder(t[p].ls,joiner);postorder(t[p].rs,joiner);joiner.add(t[p].v + ""); //后序输出}}public static void main(String[] args) {Scanner sc = new Scanner(System.in);int n = sc.nextInt();for (int i = 1; i <= n; i++) {int a = sc.nextInt(), b = sc.nextInt();t[i] = new Node(i, a, b);}StringJoiner joiner = new StringJoiner(" ");        preorder(1, joiner);        System.out.println(joiner);        joiner = new StringJoiner(" ");midorder(1, joiner);        System.out.println(joiner);joiner = new StringJoiner(" ");postorder(1, joiner);       System.out.println(joiner);}
}

(3)Python代码

N = 100005
t = [0] * N  # tree[0]不用,0表示空结点
class Node:def __init__(self, v, ls, rs):self.v = vself.ls = lsself.rs = rsdef preorder(p):  # 求先序序列if p != 0:print(t[p].v, end=' ')  # 先序输出preorder(t[p].ls)preorder(t[p].rs)def midorder(p):  # 求中序序列if p != 0:midorder(t[p].ls)print(t[p].v, end=' ')  # 中序输出midorder(t[p].rs)def postorder(p):  # 求后序序列if p != 0:postorder(t[p].ls)postorder(t[p].rs)print(t[p].v, end=' ')  # 后序输出n = int(input())
for i in range(1, n+1):a, b = map(int, input().split())t[i] = Node(i, a, b)preorder(1);  print()
midorder(1);  print()
postorder(1); print()

4 习题

完全二叉树的权值

FBI树

American Heritage

求先序排列

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

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

相关文章

【大数据进阶第三阶段之Datax学习笔记】阿里云开源离线同步工具Datax快速入门

【大数据进阶第三阶段之Datax学习笔记】阿里云开源离线同步工具Datax概述 【大数据进阶第三阶段之Datax学习笔记】阿里云开源离线同步工具Datax快速入门 【大数据进阶第三阶段之Datax学习笔记】阿里云开源离线同步工具Datax类图 【大数据进阶第三阶段之Datax学习笔记】使用…

看直播怎么录屏?精选工具助你轻松录制!

随着网络直播平台的兴起&#xff0c;观看直播已经成为人们日常生活的一部分。然而&#xff0c;有时我们可能想要保存直播内容以便日后回顾或分享。可是看直播怎么录屏呢&#xff1f;在本文中&#xff0c;我们将介绍两种录制直播的方法&#xff0c;通过这些步骤&#xff0c;你可…

Verilog学习记录

目录 一、Verilog简介 &#xff08;一&#xff09;Verilog 的主要特性 &#xff08;二&#xff09;Verilog的主要应用 &#xff08;三&#xff09;Verilog设计方法 二、Verilog基础语法 &#xff08;一&#xff09;标识符和关键字 &#xff08;二&#xff09;Verilog数据…

内外网文件交换系统实用技巧揭秘:安全、效率、便捷一个不少

内外网文件交换系统是一种专门设计用于在企业内部网络&#xff08;内网&#xff09;与外部网络&#xff08;外网&#xff09;之间安全传输文件的技术解决方案。在企业环境中&#xff0c;出于安全考虑&#xff0c;内部网络通常与外部网络隔离&#xff0c;以防止未经授权的访问和…

shp文件与数据库(创建表)

前言 第三方库准备 shp文件是什么&#xff1f;笔者就不多做解释。后面将使用python的一些第三方库 1、sqlalchemy 2、pyshp 3、geoalchemy2 4、geopandas 这四个是主要的库&#xff0c;具体怎么使用可以参考相关教程&#xff0c;当然还有其他库&#xff0c;后面在介绍。…

信源编码与信道转移矩阵

目录 一. 信息论模型 二. 点对点通信模型 三. 信源编码 四. 信道转移矩阵 4.1 二进制对称信道 4.2 二进制擦除信道 五. 小结 &#xff08;1&#xff09;信道直射与反射 &#xff08;2&#xff09;信道散射 &#xff08;3&#xff09; 信道时变性 一. 信息论模型 194…

【AI视野·今日Robot 机器人论文速览 第七十一期】Fri, 5 Jan 2024

AI视野今日CS.Robotics 机器人学论文速览 Fri, 5 Jan 2024 Totally 11 papers &#x1f449;上期速览✈更多精彩请移步主页 Daily Robotics Papers Machine Learning in Robotic Ultrasound Imaging: Challenges and Perspectives Authors Yuan Bi, Zhongliang Jiang, Felix D…

redis可视化工具 RedisInsight

redis可视化工具 RedisInsight 1、RedisInsight是什么2、下载RedisInsight3、使用RedisInsight4、其他redsi可视化工具 1、RedisInsight是什么 RedisInsight 是一个用于管理和监控 Redis 数据库的图形用户界面&#xff08;GUI&#xff09;工具。它是由 Redis Labs 开发的&…

idea使用ssh连接docker,并通过Dockerfile文件,直接在idea中启动docker应用,并进行远程debug

idea使用ssh连接docker&#xff0c;并通过Dockerfile文件&#xff0c;直接在idea中启动docker应用&#xff0c;并进行远程debug 第一步: idea通过ssh连接docker第二步&#xff1a;使用Dockerfile文件在远程启动应用第三步: 远程debug 容器运行的好处是减轻本地运行的负担(本地电…

NSSCTF 2048

开启环境: 按F12查看网络,看到2048.js文件,打开 修改score>20000或者直接运行:(控制台输入) alert(String.fromCharCode(24685,21916,33,102,108,97,103,123,53,51,49,54,48,99,56,56,56,101,50,53,99,51,102,56,50,56,98,50,51,101,51,49,54,97,55,97,101,48,56,51,125)); …

Quartus II 13.1的安装及使用

Quartus II 13.1的安装及使用_quartus13.1-CSDN博客1.3 Verilog 环境搭建 | 菜鸟教程 学习 Verilog 做仿真时&#xff0c;可选择不同仿真环境。FPGA 开发环境有 Xilinx 公司的 ISE&#xff08;目前已停止更新&#xff09;&#xff0c;VIVADO&#xff1b;因特尔公司的 Quartu…

Marching Cubes算法再回顾

1,确定包含等值面的体元 首先介绍一下 体元的概念&#xff0c;体元是三维图像中由相邻的八个体素点组成的正方体方格&#xff0c;英语也叫 Cube&#xff0c;体元中角点函数值分为两种情况&#xff0c;一种是大于等于给定等值面的值 C0 ,则将角点设为 1 称该角点在等值面内部&a…

本地部署 gemini-openai-proxy,使用 Google Gemini 实现 Openai API

本地部署 gemini-openai-proxy&#xff0c;使用Google Gemini 实现 Openai API 0. 背景1. 申请 Google Gemini API key2. (Optional)Google Gemini 模型说明3. gemini-openai-proxy Github 地址4. 本地部署 gemini-openai-proxy5. 测试 0. 背景 使用 Google Gemini 实现 Opena…

Java 之 CAS(CompareAndSwap)底层原理详解

目录 一. 前言 二. CAS 底层原理 2.1. 代码实例 2.2. 源码分析 2.3. 底层汇编 2.4. ABA 问题 三. 总结 3.1. CAS 缺点 3.2. CAS 会导致 ABA 问题 一. 前言 CAS 的全称是 Compare-And-Swap&#xff0c;它是 CPU 并发原语。它的功能是判断内存某个位置的值是否为预期值。…

MySQL 8.0 开关 Redo Logging

一 前言 前几天有客户测试使用云数据库的时候提出 要禁止mydumper 关闭redo log的操作 (说白了就是导入数据时保持MySQL 实例的redo logging功能)&#xff0c; 这才想起 在 MySQL 8.0.21 版本中&#xff0c;开启了一个新特性 “Redo Logging 动态开关”。 在新实例导数据的场…

【IPC通信--消息队列】

消息队列&#xff08;也叫做报文队列&#xff09;是一个消息的链表。可以把消息看作一个记录&#xff0c;具有特定的格式以及特定的优先级。对消息队列有写权限的进程可以向消息队列中按照一定的规则添加新消息&#xff1b;对消息队列有读权限的进程则可以从消息队列中读走消息…

[C#]Onnxruntime部署Chinese CLIP实现以文搜图以文找图功能

【官方框架地址】 https://github.com/OFA-Sys/Chinese-CLIP 【算法介绍】 在当今的大数据时代&#xff0c;文本信息处理已经成为了计算机科学领域的核心议题之一。为了高效地处理海量的文本数据&#xff0c;自然语言处理&#xff08;NLP&#xff09;技术应运而生。而在诸多N…

电子实验室设备:从零开始配置实验室(一)

本文译自 Electronics Lab Equipment: Kitting out a Lab from Scratch 随着多次国际迁徙以及在几家公司&#xff08;或其分支机构&#xff09;工作&#xff0c;尤其是在没有强大电子工程团队的情况下&#xff0c;我不得不为自己和客户设置多个电子实验室。那些计划进行内部测试…

网页设计与制作web前端设计html+css+js成品。电脑网站制作代开发。vscodeDrea 【企业公司宣传网站(HTML静态网页项目实战)附源码】

网页设计与制作web前端设计htmlcssjs成品。电脑网站制作代开发。vscodeDrea 【企业公司宣传网站&#xff08;HTML静态网页项目实战&#xff09;附源码】 https://www.bilibili.com/video/BV1Hp4y1o7RY/?share_sourcecopy_web&vd_sourced43766e8ddfffd1f1a1165a3e72d7605

【C++】STL 算法 ⑥ ( 二元谓词 | std::sort 算法简介 | 为 std::sort 算法设置 二元谓词 排序规则 )

文章目录 一、二元谓词1、二元谓词简介2、 std::sort 算法简介3、 代码示例 - 为 std::sort 算法设置 二元谓词 排序规则 一、二元谓词 1、二元谓词简介 " 谓词 ( Predicate ) " 是一个 返回 布尔 bool 类型值 的 函数对象 / 仿函数 或 Lambda 表达式 / 普通函数 , …