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

【数据结构】二叉树———Lesson2

Hi~!这里是奋斗的小羊,很荣幸您能阅读我的文章,诚请评论指点,欢迎欢迎 ~~
💥💥个人主页:奋斗的小羊
💥💥所属专栏:C语言

🚀本系列文章为个人学习笔记,在这里撰写成文一为巩固知识,二为展示我的学习过程及理解。文笔、排版拙劣,望见谅。


目录

  • 前言
  • 一、TOP-K问题
  • 二、二叉树的链式结构
    • 2.1前中后序遍历
    • 2.2节点个数
    • 2.3叶子个数
    • 2.4高度 / 深度
    • 2.5第K层节点数
    • 2.6查找值为x的节点
    • 2.7二叉树销毁
    • 2.8相关OJ题
    • 2.9层序遍历
  • 总结

前言

在TOP-K问题中有一种方法能在占用很小空间的情况下高效地找出最大或最小的前K个数。
在上篇文章介绍树时说树是递归定义的,因此二叉树的遍历、二叉树的搜索、二叉树的深度、高度、节点数、二叉树的路径求解等问题,基本都会用递归解决。


一、TOP-K问题

接上篇文章,我们简单地了解了TOP-K问题,介绍了如何从比较大的数据量中快速找出最大(最小)的前K个数据。

| 方法一:

用这些较大的数据量建堆,循环Top、Pop,找出最大(最小)的前K个数。

但是这个方法有个致命缺陷,它只适合数据量还不是特别大的情况,因为如果数据量非常大时我们还建堆的话,这对空间的消耗是很大的,那我们就要想别的办法了。如果数据海量,但我们现在只有1GB的内存,直接建堆显然行不通。

| 方法二:

将这海量数据分成合适的若干份分别建堆,找出每份中的最大(最小)的前K的数,再将这些数建堆,循环Top、Pop K次就能找到最大(最小)的前K个数。

但是这个方法也不是特别好,因为1GB的内存还是比较大的,假如这个问题非要搞我们,它有海量的数据但是只给我们1KB的内存,甚至更狠一点只给我们100Byte的空间,这时候方法二就显得力不从心了,因为这个若干份将会非常大,非常不理想。

| 方法三:

先从这海量数据中拿出前K个数建小堆(大堆),然后再不断拿出剩下的数和堆顶数据比较,如果大(小)于堆顶就替换掉堆顶,再向下调整保证堆成立,当这海量的数据全都比完后,留在堆内的数就是这海量数据中最大(最小)的前K个数。

这个方法需要注意的是如果要求我们找最大的前K个数要建小堆最小的前K个数要建大堆。当然K也不能太大,要是我们现在可用的内存连这K个数都装不下那就有点扯淡了。

方法三代码如下:

void test1()
{FILE* pf = fopen("data.txt", "w");if (pf == NULL){perror("fopen fail");return;}//产生随机的100000个数存到磁盘中for (int i = 0; i < 100000; i++){//rand函数产生的随机数有重复,+i减少重复的数int ret = rand() + i;fprintf(pf, "%d\n", ret);}fclose(pf);pf = NULL;
}void test2()
{FILE* pf = fopen("data.txt", "r");if (pf == NULL){perror("fopen fail");return;}int k = 0;scanf("%d", &k);int* arr = (int*)malloc(k * sizeof(int));if (arr == NULL){perror("malloc fail");return;}//读取k个数到数组中for (int i = 0; i < k; i++){fscanf(pf, "%d", &arr[i]);}//k个数建小堆for (int i = (k - 1 - 1) / 2; i >= 0; i--){AdjustDown(arr, i, k);}//读取剩下的数与堆顶比较int ret = 0;while (fscanf(pf, "%d", &ret) > 0){if (ret > arr[0]){arr[0] = ret;AdjustDown(arr, 0, k);}}//留在堆内的数就是所有数中最大的前K个数for (int i = 0; i < k; i++){printf("%d ", arr[i]);}fclose(pf);pf = NULL;
}int main()
{srand((unsigned int)time(NULL));test1();test2();return 0;
}

这里又有个问题,我们怎么知道这K个数就是最大的前K个数呢?如何验证?

为了验证我们这个程序有没什么问题,这里有个简单的小方法,我们可以手动地在已经产生了100000个随机数的文件中修改K个使它们一定是最大的K个数,然后再运行程序看看是否有问题。运行前先把产生随机数的函数屏蔽掉。

在这里插入图片描述

可以看到此时打印出来的10个数就是我们故意放进去的最大的10个数。


二、二叉树的链式结构

在上篇文章中简单地了解了二叉树的链式存储,即用链表来表示一棵二叉树,用链表来指示元素的逻辑关系。
通常每个节点由三个域组成,一个数据域和两个指针域,分别用左指针和右指针来指向左孩子和右孩子。链式结构又分为二叉链和三叉链,当前我们学习的是二叉链,三叉链会在后面的学习中学到。

typedef int BTDataType;
//二叉链
typedef struct BinTreeNode
{struct BinTreeNode* pleft;//左孩子struct BinTreeNode* pright;//右孩子BTDataType data;
}BTNode;

二叉树的创建方式比较复杂,后续我们会深入学习,这里为了测试下面将要介绍的二叉树遍历,我们先手动创建一棵链式二叉树。

#define  _CRT_SECURE_NO_WARNINGS#include <stdio.h>
#include <stdlib.h>typedef int BinTreeType;typedef struct BinaryTreeNode
{BinTreeType data;struct BinaryTreeNode* left;struct BinaryTreeNode* right;
}BTNode;BTNode* BuyNode(BinTreeType x)
{BTNode* node = (BTNode*)malloc(sizeof(BTNode));if (node == NULL){perror("malloc fail");return;}node->data = x;node->left = node->right = NULL;return node;
}BTNode* GreatBinaryTree()
{BTNode* node1 = BuyNode(1);BTNode* node2 = BuyNode(2);BTNode* node3 = BuyNode(3);BTNode* node4 = BuyNode(4);BTNode* node5 = BuyNode(5);BTNode* node6 = BuyNode(6);node1->left = node2;node1->right = node4;node2->left = node3;node4->left = node5;node4->right = node6;return node1;
}int main()
{BTNode* root = GreatBinaryTree();return 0;
}

2.1前中后序遍历

在这里插入图片描述

二叉树的操作离不开树的遍历,按照规则,二叉树的遍历有:前序、中序、后序(前根序、中根序、后根序)的递归结构遍历。

  • 前序: 访问顺序为根节点、左子树、右子树

A B D N N N C E N N F N N

  • 中序: 访问顺序为左子树、根节点、右子树

N D N B N A N E N C N F N

  • 后序: 访问顺序为左子树、右子树、根节点

N N D N B N N E N N F C A

代码实现:

void PrevOrder(BTNode* root)
{if (root == NULL){printf("N ");return;}printf("%d ", root->data);PrevOrder(root->left);PrevOrder(root->right);
}void InOrder(BTNode* root)
{if (root == NULL){printf("N ");return;}InOrder(root->left);printf("%d ", root->data);InOrder(root->right);
}void PostOrder(BTNode* root)
{if (root == NULL){printf("N ");return;}PostOrder(root->left);PostOrder(root->right);printf("%d ", root->data);
}

请添加图片描述
请添加图片描述
请添加图片描述


2.2节点个数

如何计算节点的个数呢?可能有同学会想到用上面学到的前中后序遍历二叉树++计数:

int TreeSize(BTNode* root)
{int size = 0;if (root == NULL){printf("N ");return;}size++;printf("%d ", root->data);TreeSize(root->left);TreeSize(root->right);return size;
}

但这样是行不通的,因为上面我们前中后序遍历二叉树是递归实现的,每一次递归函数栈帧内都重新定义了size
那可能又有同学说用static修饰size不就好了,但是这个方法也不太能行得通。

int TreeSize(BTNode* root)
{static int size = 0;if (root == NULL){printf("N ");return;}size++;printf("%d ", root->data);TreeSize(root->left);TreeSize(root->right);return size;
}

请添加图片描述

可以看到用static修饰后这个方法也只能计算一次,因为static修饰的变量在静态区,程序运行结束才销毁。
我们可以考虑用递归的思想解决这个问题。因为一个二叉树的节点个数是左子树节点个数+右子树节点个数+1(根节点),左子树的节点个数又是它的左子树节点个数+右子树节点个数+1(根节点),所以我们可以用递归解决这个问题。

在这里插入图片描述

递归计算节点数代码如下:

int TreeSize(BTNode* root)
{if (root == NULL){return 0;}return TreeSize(root->left) + TreeSize(root->right) + 1;
}

2.3叶子个数

如果节点的左指针和右指针都指向NULL,那这个节点就是叶子,如果节点为空就返回0。

int TreeLeafSize(BTNode* root)
{if (root == NULL){return 0;}if (root->left == NULL && root->right == NULL){return 1;}return TreeLeafSize(root->left) + TreeLeafSize(root->right);
}

2.4高度 / 深度

一个二叉树的高度是左子树高度和右子树高度大的一个再加一,左子树的高度又是它的左子树高度和右子树高度大的一个再加一,这显然又是一个递归问题。

int TreeHight(BTNode* root)
{ if (root == NULL){return 0;}int lefthight = TreeHight(root->left);int leftright = TreeHight(root->right);return lefthight > leftright ? lefthight + 1 : leftright + 1;
}

这里需要注意要用一个值来接收左右子树的高度,不要写成下面这种:

int TreeHight(BTNode* root)
{ if (root == NULL){return 0;}return TreeHight(root->left) > TreeHight(root->right) ? TreeHight(root->left) + 1 : TreeHight(root->right) + 1;
}

虽然下面这种看起来更简单,但是当二叉树的深度比较深时,这个代码的时间消耗是非常非常非常大的。


2.5第K层节点数

求第K层的节点数,就是相对于第二层来说求第K-1层节点数,相对于第三层来说求第K-2层节点数,也可以用递归解决,当节点不为空且K==1时返回1。

int TreeKSize(BTNode* root, int k)
{if (root == NULL){return 0;}if (k == 1){return 1;}return TreeKSize(root->left, k - 1) + TreeKSize(root->right, k - 1);
}

2.6查找值为x的节点

查找值为x的节点可以用前序遍历二叉树解决,当节点值等于x时返回节点指针,如果不等于则查找左子树,如果左子树找到了就返回节点指针,如果没找到(返回NULL)则查找右子树,不管找没找到都返回右子树的返回值。

BTNode* TreeFind(BTNode* root, BinTreeType x)
{if (root == NULL){return NULL;}if (root->data == x){return root;}BTNode* node = TreeFind(root->left, x);if (node)//如果为空则左子树没找到{return node;}return TreeFind(root->right, x);
}

2.7二叉树销毁

//二叉树销毁
void TreeDestroy(BTNode* root)
{assert(root);if (root == NULL){return;}TreeDestroy(root->left);TreeDestroy(root->right);free(root);
}

二叉树销毁函数调用完记得给rootNULL


2.8相关OJ题

Leetcode—单值二叉树

bool isUnivalTree(struct TreeNode* root) {if (root == NULL){return true;}if (root->left && root->left->val != root->val){return false;}if (root->right && root->right->val != root->val){return false;}return isUnivalTree(root->left) && isUnivalTree(root->right);
}

Leetcode—相同的树

bool isSameTree(struct TreeNode* p, struct TreeNode* q) {if (p == NULL && q == NULL){return true;}if (p == NULL || q == NULL){return false;}if (p->val != q->val){return false;}return isSameTree(p->left, q->left) && isSameTree(p->right, q->right);
}

Leetcode—对称二叉树

bool _isSymmetric(struct TreeNode* p, struct TreeNode* q) {if (p && q){if (p->val != q->val){return false;}return _isSymmetric(p->left, q->right) && _isSymmetric(p->right, q->left);}if (p == q){return true;}return false;
}
bool isSymmetric(struct TreeNode* root) {if (root == NULL){return true;}return _isSymmetric(root->left, root->right);
}

Leetcode—二叉树的前序遍历

int TreeSize(struct TreeNode* root)
{if (root == NULL){return 0;}return TreeSize(root->left) + TreeSize(root->right) + 1;
}
void PreOrder(struct TreeNode* root, int* arr, int* pi)
{if (root == NULL){return;}//每次递归都会建立新的栈帧空间,不同的栈帧空间内相同的变量之间互不影响,//而我们需要的是每次函数递归都要改变下标,所以需要传地址。arr[(*pi)++] = root->val;PreOrder(root->left, arr, pi);PreOrder(root->right, arr, pi);
}
int* preorderTraversal(struct TreeNode* root, int* returnSize) {*returnSize = TreeSize(root);//在开辟空间前可以先算出节点个数以开辟合适的空间int* arr = (int*)malloc(*returnSize * sizeof(int));int i = 0;PreOrder(root, arr, &i);return arr;
}

函数每次递归都会建立独立的栈帧空间,同一个变量在不同的栈帧空间中互不影响,如果我们想让某一变量在每次函数递归都改变,则应该传变量地址。
Leetcode—另一棵树的子树

bool isSameTree(struct TreeNode* p, struct TreeNode* q)
{if (p == NULL && q == NULL){return true;}if (p == NULL || q == NULL){return false;}if (p->val != q->val){return false;}return isSameTree(p->left, q->left) && isSameTree(p->right, q->right);
}
bool isSubtree(struct TreeNode* root, struct TreeNode* subRoot){if (root == NULL){return false;}if (root->val == subRoot->val && isSameTree(root, subRoot)){return true;}return isSubtree(root->left, subRoot) || isSubtree(root->right, subRoot);
}

我们知道二叉树是由根节点和左右子树构成,因此我们可以先判断两个根节点是否相等,如果相等且左右子树也相等则两个二叉树互为子树;如果根节点不相等则递归判断左子树或右子树。


2.9层序遍历

顾名思义层序遍历就是一层一层的遍历二叉树,规则是将根节点插入队列中,取出根节点后将根节点的两个子节点(也就是第二层)带入队列中,取出左节点后又将左节点的两个子节点带入队列中,依次遍历完整个二叉树。

//层序遍历
void TreeLevelOrder(BTNode* root)
{assert(root);Que q;QueueInit(&q);if (root){QNodePush(&q, root);}while (!QNodeEmpty(&q)){BTNode* front = QNodeFront(&q);QNodePop(&q);printf("%d ", front->data);if (front->left){QNodePush(&q, front->left);}if (front->right){QNodePush(&q, front->right);}}QNodeDestroy(&q);
}

总结

  • 二叉树由根节点、左子树和右子树组成,每个子树也是一个二叉树。递归方法很适合处理这种具有递归结构的数据结构,例如通过递归函数不断地遍历左右子树。递归的思想可以帮助我们分解复杂问题,将大问题转化为相同结构的小问题,从而简化解题过程。

相关文章:

【数据结构】二叉树———Lesson2

Hi~&#xff01;这里是奋斗的小羊&#xff0c;很荣幸您能阅读我的文章&#xff0c;诚请评论指点&#xff0c;欢迎欢迎 ~~ &#x1f4a5;&#x1f4a5;个人主页&#xff1a;奋斗的小羊 &#x1f4a5;&#x1f4a5;所属专栏&#xff1a;C语言 &#x1f680;本系列文章为个人学习…...

mongodb数据导出与导入

一、先去检查mongodump mongodump --version 如果报 mongodump version: built-without-version-string 或者其他的较老的版本&#xff0c;直接去下载最新的【传送门】 【以Ubuntu18.04为例】 安装工具 假设你下载的是 .tgz 文件&#xff08;适用于 Linux 系统&#xff09;&am…...

电路学习——经典运放电路之滞回比较器(施密特触发器)(2024.07.18)

参考链接1: 电子设计教程29&#xff1a;滞回比较器&#xff08;施密特触发器&#xff09; 参考链接2: 滞回比较器电路详细分析 参考链接3: 比较器精髓&#xff1a;施密特触发器&#xff0c;正反馈的妙用 参考链接4: 比较器反馈电阻选多大&#xff1f;理解滞后效应&#xff0c;轻…...

NVIDIA Container Toolkit 安装与配置帮助文档(Ubuntu,Docker)

NVIDIA Container Toolkit 安装与配置帮助文档(Ubuntu,Docker) 本文档详细介绍了在 Ubuntu Server 22.04 上使用 Docker 安装和配置 NVIDIA Container Toolkit 的过程。 概述 NVIDIA 容器工具包使用户能够构建和运行 GPU 加速容器。即可以在容器中使用NVIDIA显卡。 架构图如…...

JavaWeb day01-HTML入门

Web前端 课程安排 HTML、CSS简介 HTML快速入门 实现标题排版 新闻标题样式...

驱动框架——CMSIS第一部分 RTE驱动框架介绍

一、介绍CMISIS 什么是CMSIS&#xff08;cortex microcontrol software interface standard一种软件标准接口&#xff09;&#xff0c;官网地址&#xff1a;https://arm-software.github.io/CMSIS_6/latest/General/index.html 包含的core、driver、RTOS、dsp、nn等部分&…...

Debezium日常分享系列之:Debezium2.7版本PostgreSQL数据库连接器

Debezium日常分享系列之:Debezium2.7版本PostgreSQL数据库连接器 一、概述二、连接器的工作原理安全快照初始快照的默认工作流程行为临时快照触发临时增量快照触发临时阻塞快照增量快照增量快照流程Debezium 如何解决具有相同主键的记录之间的冲突快照窗口触发增量快照具有附加…...

保障信息系统安全保护等级调整期间的安全性

保障信息系统安全保护等级调整期间的安全性&#xff1a; 策略与实践 在当今数字化时代&#xff0c;信息系统已成为企业和组织运营的核心支撑。为了适应不断变化的业务需求和安全威胁环境&#xff0c;信息系统安全保护等级的调整成为必要之举。然而&#xff0c;这一调整过程可能…...

实战:shell编程之全量命令练习

概叙 槽点~~~~~~~&#xff01; 往期shell相关文章回顾&#xff0c;有兴趣的可以自行阅读和练习。 科普文&#xff1a;一文搞懂Vim-CSDN博客 科普文&#xff1a;jvm笔记-CSDN博客 科普文&#xff1a;一天学会shell编程-CSDN博客 科普文&#xff1a;Linux服务器巡检小结_lin…...

在 CentOS 7 上编译安装 Python 3.11

安装必要的依赖 首先&#xff0c;你需要安装一些开发工具和库&#xff0c;以便编译 Python 和 OpenSSL&#xff1a; yum -y groupinstall "Development tools" yum install -y wget gcc-c pcre pcre-devel zlib zlib-devel libffi-devel zlib1g-dev openssl-devel …...

Qt 4.8.7 + MSVC 中文乱码问题深入分析

此问题很常见&#xff0c;然而网上关于此问题的分析大多不够深刻&#xff0c;甚至有错误&#xff1b;加之Qt5又更改了一些编码策略&#xff0c;而很多文章并未提及版本问题&#xff0c;或是就算提了&#xff0c;读者也不重视。这些因素很容易让读者产生误导。今日我彻底研究透了…...

IDEA的常见代码模板的使用

《IDEA破解、配置、使用技巧与实战教程》系列文章目录 第一章 IDEA破解与HelloWorld的实战编写 第二章 IDEA的详细设置 第三章 IDEA的工程与模块管理 第四章 IDEA的常见代码模板的使用 第五章 IDEA中常用的快捷键 第六章 IDEA的断点调试&#xff08;Debug&#xff09; 第七章 …...

arcgis怎么选取某个指定区域地方的数据,比如从全国乡镇数据选取长沙市乡镇数据

一共5个步骤&#xff0c;没一句废话&#xff0c;耐心看完。看完你就会在任何软件选取指定范围的数据了。 一、如图&#xff0c;先将数据加载到arcgis里面&#xff0c;我们要选取里面长沙市的范围数据。 二、选取长沙市的语句 “市” like ‘长沙%’ 切记&#xff0c;切记&…...

二、链表(1)

203.移除链表元素 创建一个虚拟哨兵头节点&#xff0c;就不用考虑原本头结点要不要删除 # Definition for singly-linked list. # class ListNode: # def __init__(self, val0, nextNone): # self.val val # self.next next class Solution:def remove…...

KAFKA搭建教程

KAFKA搭建教程 期待您的关注 KAFKA学习笔记 帮助更多人 目录 KAFKA搭建教程 1.下载Kafka并解压 2.添加环境变量 3.修改 server.properties 文件 4.将kafka复制到其它节点 5.修改node1、node2节点的broker.id 6.将master的环境变量同步到node1、 node2 7.启动zookeeper…...

Linux网络——套接字与UdpServer

目录 一、socket 编程接口 1.1 sockaddr 结构 1.2 socket 常见API 二、封装 InetAddr 三、网络字节序 四、封装通用 UdpServer 服务端 4.1 整体框架 4.2 类的初始化 4.2.1 socket 4.2.2 bind 4.2.3 创建流式套接字 4.2.4 填充结构体 4.3 服务器的运行 4.3.1 rec…...

SpringBoot源码深度解析

今天&#xff0c;聊聊SpringBoot的源码&#xff0c;本博客聊的版本为v2.0.3.RELEASE。目前SpringBoot的最新版为v3.3.2&#xff0c;可能目前有些公司使用的SpringBoot版本高于我这个版本。但是没关系&#xff0c;因为版本越新&#xff0c;新增的功能越多&#xff0c;反而对Spri…...

【Qt】常用控件

文章目录 QWidgetenabledgeometrywindow framewindowTitlewindowIconqrc资源管理windowOpacitycursorfonttoolTipfocusPolicystyleSheet 按钮类PushButtonRadioButtonCheckBoxSignals 显示类LabelLCDNumberProgressBarCalendar 输入类LineEditTextEditComboBoxSpinBoxDateTimeE…...

electron 主进程和渲染进程通信

在Electron中,主进程(main process)和渲染进程(renderer process)之间的通信是非常重要的,因为Electron应用通常会将用户界面(由Web技术如HTML, CSS, 和JavaScript构建)和原生功能(如系统对话框、文件I/O等)分开处理。主进程管理应用的生命周期和创建渲染进程,而渲染…...

【ARM】MDK-解决CMSIS_DAP.DLL missing报错

【更多软件使用问题请点击亿道电子官方网站】 1、 文档目标 记录解决CMSIS_DAP.DLL missing的报错情况&#xff0c;对应相关报错信息&#xff0c;供后续客户参考&#xff0c;快速解决客户问题。 2、 问题场景 客户进行硬件调试时&#xff0c;发现Target设置内有CMSIS_DAP.DL…...

XML Group端口详解

在XML数据映射过程中&#xff0c;经常需要对数据进行分组聚合操作。例如&#xff0c;当处理包含多个物料明细的XML文件时&#xff0c;可能需要将相同物料号的明细归为一组&#xff0c;或对相同物料号的数量进行求和计算。传统实现方式通常需要编写脚本代码&#xff0c;增加了开…...

python如何将word的doc另存为docx

将 DOCX 文件另存为 DOCX 格式&#xff08;Python 实现&#xff09; 在 Python 中&#xff0c;你可以使用 python-docx 库来操作 Word 文档。不过需要注意的是&#xff0c;.doc 是旧的 Word 格式&#xff0c;而 .docx 是新的基于 XML 的格式。python-docx 只能处理 .docx 格式…...

Module Federation 和 Native Federation 的比较

前言 Module Federation 是 Webpack 5 引入的微前端架构方案&#xff0c;允许不同独立构建的应用在运行时动态共享模块。 Native Federation 是 Angular 官方基于 Module Federation 理念实现的专为 Angular 优化的微前端方案。 概念解析 Module Federation (模块联邦) Modul…...

Yolov8 目标检测蒸馏学习记录

yolov8系列模型蒸馏基本流程&#xff0c;代码下载&#xff1a;这里本人提交了一个demo:djdll/Yolov8_Distillation: Yolov8轻量化_蒸馏代码实现 在轻量化模型设计中&#xff0c;**知识蒸馏&#xff08;Knowledge Distillation&#xff09;**被广泛应用&#xff0c;作为提升模型…...

使用Spring AI和MCP协议构建图片搜索服务

目录 使用Spring AI和MCP协议构建图片搜索服务 引言 技术栈概览 项目架构设计 架构图 服务端开发 1. 创建Spring Boot项目 2. 实现图片搜索工具 3. 配置传输模式 Stdio模式&#xff08;本地调用&#xff09; SSE模式&#xff08;远程调用&#xff09; 4. 注册工具提…...

CRMEB 中 PHP 短信扩展开发:涵盖一号通、阿里云、腾讯云、创蓝

目前已有一号通短信、阿里云短信、腾讯云短信扩展 扩展入口文件 文件目录 crmeb\services\sms\Sms.php 默认驱动类型为&#xff1a;一号通 namespace crmeb\services\sms;use crmeb\basic\BaseManager; use crmeb\services\AccessTokenServeService; use crmeb\services\sms\…...

Python 训练营打卡 Day 47

注意力热力图可视化 在day 46代码的基础上&#xff0c;对比不同卷积层热力图可视化的结果 import torch import torch.nn as nn import torch.optim as optim from torchvision import datasets, transforms from torch.utils.data import DataLoader import matplotlib.pypl…...

书籍“之“字形打印矩阵(8)0609

题目 给定一个矩阵matrix&#xff0c;按照"之"字形的方式打印这个矩阵&#xff0c;例如&#xff1a; 1 2 3 4 5 6 7 8 9 10 11 12 ”之“字形打印的结果为&#xff1a;1&#xff0c;…...

倒装芯片凸点成型工艺

UBM&#xff08;Under Bump Metallization&#xff09;与Bump&#xff08;焊球&#xff09;形成工艺流程。我们可以将整张流程图分为三大阶段来理解&#xff1a; &#x1f527; 一、UBM&#xff08;Under Bump Metallization&#xff09;工艺流程&#xff08;黄色区域&#xff…...

跨平台商品数据接口的标准化与规范化发展路径:淘宝京东拼多多的最新实践

在电商行业蓬勃发展的当下&#xff0c;多平台运营已成为众多商家的必然选择。然而&#xff0c;不同电商平台在商品数据接口方面存在差异&#xff0c;导致商家在跨平台运营时面临诸多挑战&#xff0c;如数据对接困难、运营效率低下、用户体验不一致等。跨平台商品数据接口的标准…...