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

数据结构——二叉树

在这里插入图片描述

本章代码仓库:堆、二叉树链式结构

文章目录

  • 🍭1. 树
    • 🧁1.1 树的概念
    • 🧁1.2 树的结构
  • 🍬2. 二叉树
    • 🍫2.1 二叉树的概念
    • 🍫2.2 特殊的二叉树
    • 🍫2.3 二叉树的性质
    • 🍫2.4 二叉树的存储结构
  • 🍯3. 堆
    • 🍼3.1 堆的实现
      • 🥛接口声明
      • 🥛接口实现
    • 🍼3.2 堆排序
      • 🥛堆排序实现
      • 🥛堆排序时间复杂度
        • ☕向下调整时间复杂度
        • ☕向上调整时间复杂度
        • ☕调堆时间复杂度
    • 🍼3.3 Top-K
  • 🍾4. 链式二叉树结构实现
    • 🍷4.1 手搓链式
    • 🍷4.2 二叉树遍历
      • 🍻前序遍历
      • 🍻中序遍历
      • 🍻后序遍历
      • 🍻层序遍历
    • 🍷4.3 二叉树结点个数
    • 🍷4.4 树的深度
    • 🍷4.5 K层结点个数
    • 🍷4.6 查找值为x的结点
    • 🍷4.6 查找值为x的结点

🍭1. 树

🧁1.1 树的概念

树是一种非线性的数据结构,由n个有限节点组成的一个具有层次关系的有限集。

在任意一颗非空的树中:

  • 有且具有一个特定的节点称为root节点
  • 除根节点外,其他节点被分成M个不互相交的有限集
  • 每棵子树根节点有且仅有一个前驱节点,可以有0个或者多个后继节点
  • 树是递归定义的

节点的度:一个节点含有的子树的个数称为该节点的度; 如上图:B的度为4

叶节点或终端节点:度为0的节点称为叶节点(没有孩子); 如上图:D、J、K、F、G、H、I

非终端节点或分支节点:度不为0的节点(有孩子); 如上图:B、C、E

双亲节点或父节点:若一个节点含有子节点,则这个节点称为其子节点的父节点; 如上图:A是B的父节点

孩子节点或子节点:一个节点含有的子树的根节点称为该节点的子节点; 如上图:B是A的孩子节点

兄弟节点:具有相同父节点的节点互称为兄弟节点; 如上图:B、C是兄弟节点

树的度:一棵树中,最大的节点的度称为树的度; 如上图:树的度为4

节点的层次:从根开始定义起,根为第1层,根的子节点为第2层,以此类推;

树的高度或深度:树中节点的最大层次; 如上图:树的高度为4

堂兄弟节点:双亲在同一层的节点互为堂兄弟;如上图:G、H互为堂兄弟节点

节点的祖先:从根到该节点所经分支上的所有节点;如上图:A是所有节点的祖先

子孙:以某节点为根的子树中任一节点都称为该节点的子孙。如上图:所有节点都是A的子孙

森林:由m(m>0)棵互不相交的树的集合称为森林;

🧁1.2 树的结构

树的结构如果用线性结构,就会蛮复杂,假设我们知道树的度为5,那我们就可以定义一个指针数组来表示每层的节点

#define N 5
struct TreeNode
{struct TreeNode* children[N];	//指针数组
};

在一般情况下,我们都是不知道树的度,如果采用线性结构,十分不便

struct TreeNode
{SeqList sl;	//存节点指针int val;
}

image-20230803091542771

所以在实际中,一般采用孩子兄弟表示法

typedef int DateType;
struct TreeNode
{struct TreeNode* _firstChild;	//第一个孩子节点struct TreeNode* _pNextBrother;	//兄弟节点DateType _val;	//数据
};

image-20230803094458269

树在数据结构中并不常用,树在实际中的典型应用就是文件系统,一层一层的

将Code文件看作根节点,下面的cppremake-clinux等就能看作是它的孩子节点

然后这些文件里面又包含了其他文件,层层推进

image-20230803094744120

🍬2. 二叉树

🍫2.1 二叉树的概念

二叉树可以看作一个进行了“计划生育”的树

image-20230803095806081

二叉树的特点:

  • 每个节点至多有两颗子树(不存在度大于2的节点)
  • 左子树右子树有顺序,次序不可颠倒(好比人的左右手),即使某个节点只要一棵子树,也要区分是左子树还是右子树

🍫2.2 特殊的二叉树

  1. 满二叉树

    满二叉树就是所有的分支节点都有左右子树,并且所有叶子都在同一层

    假设二叉树的深度为K,则总节点数则为2k-1

    image-20230803100339434

  2. 完全二叉树

    完全二叉树从根节点开始,从左到右依次填充节点,直到最后一层,最后一层的节点可以不满,但节点都尽量靠左排列

    满二叉树定是完全二叉树(正方形也是一种特殊的长方形)

    image-20230803102737902

🍫2.3 二叉树的性质

  1. 一颗非空二叉树第i层至多有**2i-1**个结点

  2. 深度为k的二叉树至多有2k-1 个结点

  3. 对于任何一颗二叉树,如果终端叶子节点为n0,度为2的结点数为n2,则n0 = n2 + 1

  4. 有n个结点的满二叉树的深度h = log2(n+1)

    高度为h的完全二叉树,结点数量范围:[2h-1,2h-1]

  5. 对于具有n个结点的完全二叉树,如果按照从上至下从左至右的数组顺序对所有节点从0开始编号,则对 于序号为i的结点有:

    • 若i>0,i位置节点的双亲序号:(i-1)/2;i=0,i为根节点编号,无双亲节点
    • 若2i+1<n,左孩子序号:2i+1,2i+1>=n否则无左孩子
    • 若2i+2<n,右孩子序号:2i+2,2i+2>=n否则无右孩子

🍫2.4 二叉树的存储结构

二叉树的存储结构可分为顺序存储和链式存储:

  1. 顺序存储

    顺序存储就是用数组来存储,这一般适用于完全二叉树,因为这样不会造成空间的浪费

    这在物理上是一个数组,但在逻辑上是一颗二叉树

  2. 链式存储

    顾名思义,采用链表来表示这颗二叉树

    typedef int DateType;
    struct TreeNode
    {struct TreeNode* _lChild;	//左孩子struct TreeNode* _rChild;	//右孩子DateType _val;	//数据
    };
    

🍯3. 堆

堆是一颗完全二叉树,堆中的每个节点都满足堆序性质,即在最大堆中,每个节点的值都大于或等于其子节点的值;在最小堆中,每个节点的值都小于或等于其子节点的值。

🍼3.1 堆的实现

下面以大根堆为例:

🥛接口声明

#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<stdbool.h>
#define CAPACITY 4typedef int HPDateType;
typedef struct Heap
{HPDateType* val;int _size;int _capacity;
}HP;//初始化
void HeapInit(HP* php);
//插入数据
void HeapPush(HP* php, HPDateType x);
//删除堆顶元素
void HeapPop(HP* php);
//获取堆顶元素
HPDateType HeapTop(HP* php);
//是否有元素
bool HeapEmpty(HP* php);
//获取当前堆的元素数量
int HeapSize(HP* php);
//销毁
void HeapDestroy(HP* php);void AdjustUp(HPDateType* val, int child);
void AdjustDown(HPDateType* val, int sz, int parent);
void Swap(HPDateType* x1, HPDateType* x2);

🥛接口实现

#define _CRT_SECURE_NO_WARNINGS 1
#pragma warning(disable:6031)
#include"Heap.h"//初始化
void HeapInit(HP* php)
{assert(php);php->val = (HPDateType*)malloc(sizeof(HPDateType) * CAPACITY);if (php->val == NULL){perror("malloc fail");exit(-1);}php->_size = 0;php->_capacity = CAPACITY;
}
//交换元素
void Swap(HPDateType* x1, HPDateType* x2)
{HPDateType tmp = *x1;*x1 = *x2;*x2 = tmp;
}
//向上调整 前提子树是堆
void AdjustUp(HPDateType* val, int child)
{int parent = (child - 1) / 2;while (child > 0){if (val[child] > val[parent]){Swap(&val[child], &val[parent]);child = parent;parent = (child - 1) / 2;}else{break;}}
}
//向下调整 前提:子树都是堆
void AdjustDown(HPDateType* val, int sz, int parent)
{//默认左孩子大int child = parent * 2 + 1;//至多叶子结点结束while (child < sz){//不越界 选出更大的孩子if (child+1<sz && val[child] < val[child+1]){child++;}if (val[child] > val[parent]){Swap(&val[child], &val[parent]);parent = child;child = parent * 2 + 1;}else{break;}}
}
//插入数据
void HeapPush(HP* php, HPDateType x)
{assert(php);if (php->_size == php->_capacity){//扩容HPDateType* tmp = realloc(php->val, sizeof(HPDateType) * php->_capacity * 2);if (tmp == NULL){perror("realloc fail");exit(-1);}php->val = tmp;php->_capacity *= 2;}php->val[php->_size] = x;php->_size++;AdjustUp(php->val, php->_size - 1);
}
//删除堆顶元素
void HeapPop(HP* php)
{assert(php);assert(!HeapEmpty(php));Swap(&php->val[0], &php->val[php->_size - 1]);php->_size--;AdjustDown(php->val, php->_size, 0);
}
//获取堆顶元素
HPDateType HeapTop(HP* php)
{assert(php);return php->val[0];
}
//是否有元素
bool HeapEmpty(HP* php)
{assert(php);return php->_size == 0;
}
//获取当前堆的元素数量
int HeapSize(HP* php)
{assert(php);return php->_size;
}
//销毁
void HeapDestroy(HP* php)
{free(php->val);php->val = NULL;php->_size = 0;php->_capacity = 0;
}

🍼3.2 堆排序

🥛堆排序实现

堆排序分为两个步骤:

  1. 建堆

    排升序:建大堆

    排降序:建小堆

  2. 堆删除的思想进行排序

如果排升序,堆顶元素是最大的,将其与最后一个元素交换,这就是堆的删除操作,但我们不需要将这个数据删除,交换完不管它即可,这样最后一个元素就是最大的,然后再向下调整,再找出最大的元素,以此反复,则可完成升序的排序。

使用堆排序,不需要手搓一个数据结构堆出来,我们只需要建堆和模拟删除操作即可

//排升序 建大堆
void HeapSort(int* pa, int sz)
{//向上调整 建堆 O(N*logN)//for (int i = 0; i < sz; i++)//{//	AdjustUp(pa, i);//}//向下调整 O(N)for (int i = (sz - 1 - 1) / 2; i >= 0; --i){AdjustDown(pa, sz, i);}//向下调整排序 O(N*logN)for (int i = 0; i < sz; i++){Swap(&pa[0], &pa[sz - 1 - i]);AdjustDown(pa, sz - 1 - i, 0);}}

🥛堆排序时间复杂度

建堆操作可以采用向上调整,也可以采用向下调整,但是向下调整的效率是高于向上调整的

image-20230804161542503

☕向下调整时间复杂度

向下调整是从第h-1层开始的

层数结点数向下移动层数
12^0h-1
22^1h-2
32^2h-3
h-12^(h-2)1

调整次数:

T(N) = 2h-1 * 1 + 2h-2 * 2 + 2h-3 * 3 + … + 22 * (h-3) + 21 * (h-2) + 20 * (h-1)

化简得:T(N) = 2h -1 - h

高度为h的满二叉树结点个数为:N = 2h - 1

这样即可推出时间复杂度为:N - log2(N+1)NlogN不在一个量级,则时间复杂度为O(N)

过程示例:

on

☕向上调整时间复杂度

向上调整建堆是从第二层开始调整的

层数结点数向上移动层数
22^11
32^22
h-12^(h-2)h-2
h2^(h-1)h-1

调整次数:

T(N) = 21 * 1 + 22 * 2 + … + 2h-1 * (h-2) + 2h-1 * (h-1)

化简得:T(N) = -2h + 2 + 2h * h - 2h = 2h * h - 2h * 2 + 2

高度为h的满二叉树结点个数为:N = 2h - 1

推出时间复杂度为:(N+1)*log2(N+1) - 2*(N+1) + 2,N和logN不在一个量级,则时间复杂度为O(N*logN)

过程示例:

logN

这里也很好比较:

向上调整建堆时,结点数多的地方,调整次数多;

而向下调整建堆时,结点数多的地方,调整次数少,所以采用向下调整建堆时,效率会高于向上调整

☕调堆时间复杂度

建完堆直接,我们只能保证栈顶元素是最大/最下的,要完成排序,还需要调堆

调堆采用的是删除堆顶元素的逻辑,N个元素,每次调整的时间复杂度为:O(logN),则整个堆排序时间复杂度为:N*log(N)

🍼3.3 Top-K

在现实的世界中,大部分只关注前多少多少,例如:我国排名前十的大学、一个专业学生成绩的前五等等。

这些都是排序,如果数据量较大,数据可能不会一下子就全部加载到内存当中,那我们就可以采用Top-K的思路解决:

用数据集合中的前k个来建堆,然后再用剩余的N-K个元素依次与堆顶元素比较

  • 前k个最大元素,建小堆
  • 前k个最小元素,建大堆

例如要在十万个数据当中找出5个最大/最小的数据,只需要建一个存储5个元素的堆

以前5个最大元素为例,那就是建小堆,那堆顶元素则是最小的,每次只需将堆顶元素和数据进行对比,如果大于堆顶元素,则替换掉堆顶元素,然后进堆,这样就一直保证,堆顶元素是这个堆中最小的元素

场景模拟:

一万个小于一万的随机数,找出前k个最大元素

void Print_TopK(const char* file, int k)
{int* topk = (int*)malloc(sizeof(int) * 5);if (topk == NULL){perror("malloc fail");exit(-1);}FILE* fout = fopen(file, "r");if (fout == NULL){perror("fopen fail");exit(-1);}//读取前k个数据for (int i = 0; i < k; i++){fscanf(fout, "%d", &topk[i]);}//建小堆for (int i = (k - 2) / 2; i >= 0; i--){AdjustDown(topk, k, i);}//将剩余元素与堆顶元素比较,大于堆顶元素则替换int val = 0;int ret = fscanf(fout, "%d", &val);while (ret != EOF){if (val > topk[0]){topk[0] = val;AdjustDown(topk, k, 0);}ret = fscanf(fout, "%d", &val);}for (int i = 0; i < k; i++){printf("%d ", topk[i]);}printf("\n");free(topk);topk = NULL;fclose(fout);
}
//造数据
void CreateDate()
{int n = 10000;srand((int)time(0));const char* file = "data.txt";FILE* fin = fopen(file, "w");if (fin == NULL){perror("fopen fail");exit(-1);}for (size_t i = 0; i < n; i++){int x = rand() % 10000;fprintf(fin, "%d\n", x);}fclose(fin);
}

🍾4. 链式二叉树结构实现

🍷4.1 手搓链式

堆属于一种线性二叉树,对于链式二叉树,本次采用手搓的方式创建

typedef int BTDataType;
typedef struct BinaryTreeNode
{BTDataType data;struct BinaryTreeNode* left;struct BinaryTreeNode* right;
}BTNode;
//申请结点
BTNode* BuyNode(BTDataType x)
{BTNode* node = (BTNode*)malloc(sizeof(BTNode));if (node == NULL){perror("malloc fail");exit(-1);}node->data = x;node->left = NULL;node->right = NULL;return node;
}
//造树(手搓)
BTNode* CreatTree()
{BTNode* node1 = BuyNode(1);BTNode* node2 = BuyNode(2);BTNode* node3 = BuyNode(3);BTNode* node4 = BuyNode(4);BTNode* node5 = BuyNode(5);BTNode* node6 = BuyNode(6);BTNode* node7 = BuyNode(7);BTNode* node8 = BuyNode(8);node1->left = node2;node1->right = node4;;node2->left = node3;node3->right = node7;node7->left = node8;node4->left = node5;node4->right = node6;return node1;
}

🍷4.2 二叉树遍历

🍻前序遍历

前序遍历也叫做先序遍历,访问顺序:根 -> 左子树 -> 右子树

//前序遍历:根 左子树 右子树
void PreOrder(BTNode* root)
{if (root == NULL){printf("NULL ");return;}printf("%d ", root->data);PreOrder(root->left);PreOrder(root->right);
}

🍻中序遍历

中序遍历访问顺序:左子树 -> 根 -> 右子树

//中序遍历:左子树 根 右子树
void InOrder(BTNode* root)
{if (root == NULL){printf("NULL ");return;}InOrder(root->left);printf("%d ", root->data);InOrder(root->right);
}

🍻后序遍历

后序遍历访问顺序:左子树 -> 右子树 -> 根

//后序遍历:左子树 右子树 根
void PostOrder(BTNode* root)
{if (root == NULL){printf("NULL ");return;}PostOrder(root->left);PostOrder(root->right);printf("%d ", root->data);
}

🍻层序遍历

层序遍历与前三种不一样,层序遍历采用队列的方式实现:

首先根节点进队列,当遍历根节点之后,根节点出队列的同时把左右孩子带进去

然后再两个孩子依次出队,同时带入孩子的孩子,依次反复

void LevelOrder(BTNode* root)
{Queue q;QueueInit(&q);if (root)QueuePush(&q, root);while (!QueueEmpty(&q)){BTNode* front = QueueFront(&q);QueuePop(&q);printf("%d ", front->data);if(front->left)QueuePush(&q, front->left);if (front->right)QueuePush(&q, front->right);}QueueDestroy(&q);
}

🍷4.3 二叉树结点个数

统计左子树和右子树的结点,然后再加上自己的一个

//树的结点树
int TreeSize(BTNode* root)
{return root == NULL ? 0 : TreeSize(root->left) + TreeSize(root->right) + 1;
}

🍷4.4 树的深度

这里每次都要记录每次统计的结点个数,不然每次每层都得重新统计(如:注释代码块)

//树的深度
int TreeHeight(BTNode* root)
{if (root == NULL){return 0; }//记录深度int left = TreeHeight(root->left)+1;int right = TreeHeight(root->right)+1;printf("%d %d\n", left, right);return left>right?left:right;//return root==NULL?0: TreeHeight(root->left) > TreeHeight(root->right) ? TreeHeight(root->left)+1 : TreeHeight(root->right)+1;
}

🍷4.5 K层结点个数

//K层结点个数
int TreeKLevel(BTNode* root, int k)
{if (root == NULL)return 0;if (k == 1)return 1;int leftChild = TreeKLevel(root->left, k - 1);int rightChild = TreeKLevel(root->right, k - 1);return leftChild + rightChild;}

🍷4.6 查找值为x的结点

//查找值为x的结点
BTNode* TreeFind(BTNode* root, BTDataType x)
{if (root == NULL)return NULL;if (root->data == x)return root;//记录结点BTNode* leftNode = TreeFind(root->left, x);BTNode* rightNode = TreeFind(root->right, x);if (leftNode)return leftNode;else if (rightNode)return rightNode;return NULL;
}

root->left) > TreeHeight(root->right) ? TreeHeight(root->left)+1 : TreeHeight(root->right)+1;
}


## 4.5 K层结点个数```c
//K层结点个数
int TreeKLevel(BTNode* root, int k)
{if (root == NULL)return 0;if (k == 1)return 1;int leftChild = TreeKLevel(root->left, k - 1);int rightChild = TreeKLevel(root->right, k - 1);return leftChild + rightChild;}

🍷4.6 查找值为x的结点

//查找值为x的结点
BTNode* TreeFind(BTNode* root, BTDataType x)
{if (root == NULL)return NULL;if (root->data == x)return root;//记录结点BTNode* leftNode = TreeFind(root->left, x);BTNode* rightNode = TreeFind(root->right, x);if (leftNode)return leftNode;else if (rightNode)return rightNode;return NULL;
}

相关文章:

数据结构——二叉树

本章代码仓库&#xff1a;堆、二叉树链式结构 文章目录 &#x1f36d;1. 树&#x1f9c1;1.1 树的概念&#x1f9c1;1.2 树的结构 &#x1f36c;2. 二叉树&#x1f36b;2.1 二叉树的概念&#x1f36b;2.2 特殊的二叉树&#x1f36b;2.3 二叉树的性质&#x1f36b;2.4 二叉树的存…...

架构训练营学习笔记:5-3接口高可用

序 架构决定系统质量上限&#xff0c;代码决定系统质量下限&#xff0c;本节课串一下常见应对措施的框架&#xff0c;细节不太多&#xff0c;侧重对于技术本质有深入了解。 接口高可用整体框架 雪崩效应&#xff1a;请求量超过系统处理能力后导致系统性能螺旋快速下降 链式…...

【笔记】湖仓一体架构演进与发展

https://www.bilibili.com/video/BV1oF411F7rQ/?spm_id_from333.788.recommend_more_video.0&vd_sourcefa36a95b3c3fa4f32dd400f8cabddeaf...

政务云建设与应用解决方案[42页PPT]

导读&#xff1a;原文《政务云建设与应用解决方案[42页PPT]》&#xff08;获取来源见文尾&#xff09;&#xff0c;本文精选其中精华及架构部分&#xff0c;逻辑清晰、内容完整&#xff0c;为快速形成售前方案提供参考。 完整版领取方式 完整版领取方式&#xff1a; 如需获取完…...

20天突破英语四级高频词汇——第①天

2&#xfeff;0天突破英语四级高频词汇~第一天加油(ง •_•)ง&#x1f4aa; &#x1f433;博主&#xff1a;命运之光 &#x1f308;专栏&#xff1a;英语四级高频词汇速记 &#x1f30c;博主的其他文章&#xff1a;点击进入博主的主页 目录 2&#xfeff;0天突破英语四级…...

【网络基础实战之路】基于MGRE多点协议的实战详解

系列文章传送门&#xff1a; 【网络基础实战之路】设计网络划分的实战详解 【网络基础实战之路】一文弄懂TCP的三次握手与四次断开 【网络基础实战之路】基于MGRE多点协议的实战详解 【网络基础实战之路】基于OSPF协议建立两个MGRE网络的实验详解 PS&#xff1a;本要求基于…...

K8s实战入门(三)

文章目录 3. 实战入门3.1 Namespace3.1.1 测试两个不同的名称空间之间的 Pod 是否连通性 3.2 Pod3.3 Label3.4 Deployment3.5 Service 3. 实战入门 本章节将介绍如何在kubernetes集群中部署一个nginx服务&#xff0c;并且能够对其进行访问。 3.1 Namespace Namespace是kuber…...

Linux-centos花生壳实现内网穿透

Linux-centos花生壳实现内网穿透 官网教程 1.安装花生壳 下载网址 点击复制就可以复制下载命令了 wget "https://dl.oray.com/hsk/linux/phddns_5.2.0_amd64.rpm" -O phddns_5.2.0_amd64.rpm# 下载完成之后会多一个rpm文件 [rootlocalhost HuaSheng]# ls phddns_…...

Jackson类层次结构中的一些应用(Inheritance with Jackson)

Have a look at working with class hierarchies in Jackson. 如何在Jackson中使用类层次结构。 Inclusion of Subtype Information There are two ways to add type information when serializing and deserializing data objects, namely global default typing and per-cl…...

Python求均值、方差、标准偏差SD、相对标准偏差RSD

均值 均值是统计学中最常用的统计量&#xff0c;用来表明资料中各观测值相对集中较多的中心位置。用于反映现象总体的一般水平&#xff0c;或分布的集中趋势。 import numpy as npa [2, 4, 6, 8]print(np.mean(a)) # 均值 print(np.average(a, weights[1, 2, 1, 1])) # 带…...

SQL ASNI where from group order 顺序

SQL语句执行顺序&#xff1a; from–>where–>group by -->having — >select --> order 第一步&#xff1a;from语句&#xff0c;选择要操作的表。 第二步&#xff1a;where语句&#xff0c;在from后的表中设置筛选条件&#xff0c;筛选出符合条件的记录。 …...

springboot(39) : RestTemplate完全体

HTTP请求调用集成,支持GET,POST,JSON,Header调用,日志打印,请求耗时计算,设置中文编码 1.使用(注入RestTemplateService) Autowiredprivate RestTemplateService restTemplateService; 2.RestTemplate配置类 import org.springframework.context.annotation.Bean; import org.…...

python中计算2的32次方减1,python怎么算2的3次方

大家好&#xff0c;给大家分享一下怎么样用python编写2的n次方,n由键盘输入&#xff0c;很多人还不知道这一点。下面详细解释一下。现在让我们来看看&#xff01; ---恢复内容开始--- 1、内置函数&#xff1a;取绝对值函数abs() 2、内置函数&#xff1a;取最大值max()&#xff…...

阿里云SLB负载均衡ALB、CLB和NLB有什么区别?

阿里云负载均衡SLB分为传统型负载均衡CLB&#xff08;原SLB&#xff09;、应用型负载均衡ALB和网络型负载均衡NLB&#xff0c;三者有什么区别&#xff1f;CLB是之前的传统的SLB&#xff0c;基于物理机架构的4层负载均衡&#xff1b;ALB是应用型负载均衡&#xff0c;7层负载均衡…...

SynergyNet(头部姿态估计 Head Pose Estimation)复现 demo测试

目录 0 相关资料1 环境搭建2 安装 SynergyNet3 下载相关文件4 编译5 测试 0 相关资料 SynergyNet&#xff08;github&#xff09;&#xff1a;https://github.com/choyingw/SynergyNet 1 环境搭建 我用的AutoDL平台搭建 选择镜像 PyTorch 1.9.0 Python 3.8(ubuntu18.04) Cu…...

mysql高级(尚硅谷-夏磊)

目录 内容介绍 Linux下MySQL的安装与使用 Mysql逻辑架构 Mysql存储引擎 Sql预热 索引简介 内容介绍 1、Linux下MySQL的安装与使用 2、逻辑架构 3、sql预热 Linux下MySQL的安装与使用 1、docker安装docker run -d \-p 3309:3306 \-v /atguigu/mysql/mysql8/conf:/etc/my…...

C++实用技术(二)std::function和bind绑定器

目录 简介std::functionstd::function对象包装器std::function做回调函数 std::bind绑定器bind绑定普通函数bind绑定成员函数 简介 C11新增了std::function和std::bind。用于函数的包装以及参数的绑定。可以替代一些函数指针&#xff0c;回调函数的场景。 std::function std…...

vue框架 element导航菜单el-submenu 简单使用方法--以侧边栏举例

1、目标 实现动态增删菜单栏的效果&#xff0c;所以要在数据库中建表 2 、建表 2.1、表样式 2.2、表数据 3、实体类 import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor;import java.util.List;Data AllArgsConstructor NoArgsConstr…...

Nodejs 第八章(npm搭建私服)

构建npm私服 构建私服有什么收益吗&#xff1f; 可以离线使用&#xff0c;你可以将npm私服部署到内网集群&#xff0c;这样离线也可以访问私有的包。提高包的安全性&#xff0c;使用私有的npm仓库可以更好的管理你的包&#xff0c;避免在使用公共的npm包的时候出现漏洞。提高…...

React Native获取手机屏幕宽高(Dimensions)

import { Dimensions } from react-nativeconsole.log(Dimensions, Dimensions.get(window)) 参考链接&#xff1a; https://www.reactnative.cn/docs/next/dimensions#%E6%96%B9%E6%B3%95 https://chat.xutongbao.top/...

多模态2025:技术路线“神仙打架”,视频生成冲上云霄

文&#xff5c;魏琳华 编&#xff5c;王一粟 一场大会&#xff0c;聚集了中国多模态大模型的“半壁江山”。 智源大会2025为期两天的论坛中&#xff0c;汇集了学界、创业公司和大厂等三方的热门选手&#xff0c;关于多模态的集中讨论达到了前所未有的热度。其中&#xff0c;…...

【JVM】Java虚拟机(二)——垃圾回收

目录 一、如何判断对象可以回收 &#xff08;一&#xff09;引用计数法 &#xff08;二&#xff09;可达性分析算法 二、垃圾回收算法 &#xff08;一&#xff09;标记清除 &#xff08;二&#xff09;标记整理 &#xff08;三&#xff09;复制 &#xff08;四&#xff…...

【学习笔记】erase 删除顺序迭代器后迭代器失效的解决方案

目录 使用 erase 返回值继续迭代使用索引进行遍历 我们知道类似 vector 的顺序迭代器被删除后&#xff0c;迭代器会失效&#xff0c;因为顺序迭代器在内存中是连续存储的&#xff0c;元素删除后&#xff0c;后续元素会前移。 但一些场景中&#xff0c;我们又需要在执行删除操作…...

VisualXML全新升级 | 新增数据库编辑功能

VisualXML是一个功能强大的网络总线设计工具&#xff0c;专注于简化汽车电子系统中复杂的网络数据设计操作。它支持多种主流总线网络格式的数据编辑&#xff08;如DBC、LDF、ARXML、HEX等&#xff09;&#xff0c;并能够基于Excel表格的方式生成和转换多种数据库文件。由此&…...

软件工程 期末复习

瀑布模型&#xff1a;计划 螺旋模型&#xff1a;风险低 原型模型: 用户反馈 喷泉模型:代码复用 高内聚 低耦合&#xff1a;模块内部功能紧密 模块之间依赖程度小 高内聚&#xff1a;指的是一个模块内部的功能应该紧密相关。换句话说&#xff0c;一个模块应当只实现单一的功能…...

论文阅读:Matting by Generation

今天介绍一篇关于 matting 抠图的文章&#xff0c;抠图也算是计算机视觉里面非常经典的一个任务了。从早期的经典算法到如今的深度学习算法&#xff0c;已经有很多的工作和这个任务相关。这两年 diffusion 模型很火&#xff0c;大家又开始用 diffusion 模型做各种 CV 任务了&am…...

高分辨率图像合成归一化流扩展

大家读完觉得有帮助记得关注和点赞&#xff01;&#xff01;&#xff01; 1 摘要 我们提出了STARFlow&#xff0c;一种基于归一化流的可扩展生成模型&#xff0c;它在高分辨率图像合成方面取得了强大的性能。STARFlow的主要构建块是Transformer自回归流&#xff08;TARFlow&am…...

Appium下载安装配置保姆教程(图文详解)

目录 一、Appium软件介绍 1.特点 2.工作原理 3.应用场景 二、环境准备 安装 Node.js 安装 Appium 安装 JDK 安装 Android SDK 安装Python及依赖包 三、安装教程 1.Node.js安装 1.1.下载Node 1.2.安装程序 1.3.配置npm仓储和缓存 1.4. 配置环境 1.5.测试Node.j…...

Linux信号保存与处理机制详解

Linux信号的保存与处理涉及多个关键机制&#xff0c;以下是详细的总结&#xff1a; 1. 信号的保存 进程描述符&#xff08;task_struct&#xff09;&#xff1a;每个进程的PCB中包含信号相关信息。 pending信号集&#xff1a;记录已到达但未处理的信号&#xff08;未决信号&a…...

Android多媒体——音/视频数据播放(十八)

在媒体数据完成解码并准备好之后,播放流程便进入了最终的呈现阶段。为了确保音视频内容能够顺利输出,系统需要首先对相应的播放设备进行初始化。只有在设备初始化成功后,才能真正开始音视频的同步渲染与播放。这一过程不仅影响播放的启动速度,也直接关系到播放的稳定性和用…...