【数据结构】二叉树的四种遍历

news/2024/4/20 2:41:24/文章来源:https://blog.csdn.net/m0_73222051/article/details/129065843

写在前面

首先二叉树是一个大家族,这篇文章就讲一讲二叉树的遍历:

  • 递归遍历

  • 迭代遍历


先识概念

二叉树的存储结构,可以为顺序存储,即使用数组;也可以为链式存储,即使用链表。我们使用较多的就是链式存储结构,本篇文章就主要讲解链式存储结构

对于一些最基础的概念,这里就不过多的介绍了,大家还是翻书为妙。


再会做题

大家一定会遇到这样的题目,根据前序遍历和中序遍历,写出后序遍历。或者根据中序遍历和后序遍历写出前序遍历。(前提都是先直到中序遍历)。下面是一些比较容易理解up的视频讲解。

根据二叉图写前中后遍历

看图遍历二叉树_法一

看图遍历二叉树_法二

根据遍历结果画二叉图

常规方法

技巧方法

如果你想解决上面的问题,就不妨将这两种题型结合起来,就能完成“根据前序和中序写后序,根据中序后序写前序“这一类问题了!


学习思想

链式存储结构

//二叉树的链式存储结构
struct TreeNode 
{int val;struct TreeNode* left;struct TreeNode* right;
};

二叉树的遍历(递归法)

//前序遍历
void preorderTraversal(struct TreeNode* root) 
{if (root == NULL) return;  // 如果节点为空,返回printf("%d ", root->val);  // 先访问根节点preorderTraversal(root->left);  // 再递归遍历左子树preorderTraversal(root->right);  // 最后递归遍历右子树
}//中序遍历
void inorderTraversal(struct TreeNode* root) 
{if (root == NULL) return;  // 如果节点为空,返回inorderTraversal(root->left);  // 先递归遍历左子树printf("%d ", root->val);  // 再访问根节点inorderTraversal(root->right);  // 最后递归遍历右子树
}//后序遍历
void postorderTraversal(struct TreeNode* root) 
{if (root == NULL) return;  // 如果节点为空,返回postorderTraversal(root->left);  // 先递归遍历左子树postorderTraversal(root->right);  // 再递归遍历右子树printf("%d ", root->val);  // 最后访问根节点
}//层序遍历
int getDepth(TreeNode* root)
{if (root == NULL){return 0;}int left_depth = getDepth(root->left);int right_depth = getDepth(root->right);return (left_depth > right_depth) ? (left_depth + 1) : (right_depth + 1);
}void levelOrderHelper(TreeNode* root, int level)
{if (root == NULL){return;}if (level == 1){printf("%d ", root->val);}else if (level > 1){levelOrderHelper(root->left, level - 1);levelOrderHelper(root->right, level - 1);}
}void levelOrder(TreeNode* root)
{int depth = getDepth(root);for (int i = 1; i <= depth; i++){levelOrderHelper(root, i);}
}

二叉树的迭代遍历(非递归)

二叉树的迭代遍历其实还是不太好理解的,先掌握递归遍历为好

void preorderTraversal(struct TreeNode* root) 
{if (root == NULL) return;struct TreeNode* stack[1000];int top = -1;stack[++top] = root;while (top >= 0) {struct TreeNode* node = stack[top--];printf("%d ", node->val);if (node->right) stack[++top] = node->right;if (node->left) stack[++top] = node->left;}
}/*
1.创建一个栈,将根节点压入栈中。
2.当栈不为空时,弹出栈顶元素,访问该节点。
3.如果该节点的右孩子不为空,将右孩子压入栈中。
4.如果该节点的左孩子不为空,将左孩子压入栈中。
5.重复步骤2到4,直到栈为空。
*/
void inorderTraversal(struct TreeNode* root) 
{if (root == NULL) return;struct TreeNode* stack[1000];int top = -1;struct TreeNode* node = root;while (top >= 0 || node) {while (node) {stack[++top] = node;node = node->left;}node = stack[top--];printf("%d ", node->val);node = node->right;}
}
/*
1.如果根节点为空,直接返回;
2.初始化栈,并将根节点入栈;
3.只要栈不为空,就一直执行以下操作:a. 将当前节点的所有左子节点都入栈,直到左子树为空;b. 取出栈顶元素,输出其值,并将当前节点指向其右子节点;c. 如果右子节点不为空,将其入栈。
*///后序遍历法一
void postorderTraversal(struct TreeNode* root) 
{if (root == NULL) return;struct TreeNode* stack[1000];int top = -1;struct TreeNode* node = root;struct TreeNode* prev = NULL;while (top >= 0 || node) {while (node) {stack[++top] = node;node = node->left;}node = stack[top];if (node->right == NULL || node->right == prev) {printf("%d ", node->val);prev = node;node = NULL;--top;}else {node = node->right;}}
}
/*
1.定义一个栈和两个指针node、prev,其中node指向当前节点,prev指向上一次访问的节点。
2.如果node不为NULL,就将node入栈,并更新node为其左子节点,直到node为NULL。
3.此时stack顶部节点为左子树遍历的最后一个节点。如果stack顶部节点没有右子节点,或者其右子节点已经被访问过了(即右子节点为prev),则可以访问该节点,否则需要访问其右子节点,因此将node指向其右子节点。
4.循环执行上述步骤,直到stack为空。在遍历过程中,如果节点没有左右子节点,则可以直接访问;如果有左右子节点,则需要先遍历左右子树,最后才能访问根节点。因此在访问节点之前,需要判断该节点的左右子树是否已经被访问过,如果已经被访问过,则可以直接访问该节点,否则需要先遍历其左右子树。这就是后序遍历需要特别注意的地方。
*///后序遍历 法二
void postorderTraversal(struct TreeNode* root) {if (root == NULL) return;struct TreeNode* stack1[1000];struct TreeNode* stack2[1000];int top1 = -1, top2 = -1;stack1[++top1] = root;while (top1 >= 0) {struct TreeNode* node = stack1[top1--];stack2[++top2] = node;if (node->left) stack1[++top1] = node->left;if (node->right) stack1[++top1] = node->right;}while (top2 >= 0) {struct TreeNode* node = stack2[top2--];printf("%d ", node->val);}
}/*
它使用了两个栈来实现:
第一个栈用来辅助遍历树的节点;
第二个栈用来按后序遍历的顺序存储节点。1.从根节点开始,依次将左子树的节点入栈;
2.弹出栈顶节点,将其入第二个栈;
3.再依次将右子树的节点入第一个栈;
4.重复步骤 2 和步骤 3,直到第一个栈为空;
5.最后依次弹出第二个栈的节点,并输出它们的值。
*/// 层序遍历
void levelOrder(TreeNode* root) 
{Queue q;initQueue(&q);   //创建队列enqueue(&q, root);  //根结点入队while (!isQueueEmpty(&q))  //如果队列不空{TreeNode* node = dequeue(&q);  //结点出栈并输出printf("%d ", node->val);if (node->left)         //左结点不空,左结点入队{enqueue(&q, node->left);}if (node->right)        //右结点不空,右结点入队{enqueue(&q, node->right);}}
}
/*
将根结点入队,队不空:出栈,打印左结点不空,将左结点入栈右结点不空,将右结点入栈
*/

熟练应用

前中后序遍历——递归

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <stdlib.h>//二叉树的链式存储结构
struct TreeNode 
{int val;struct TreeNode* left;struct TreeNode* right;
};//二叉树的先序递归创建
struct TreeNode* createTree() 
{int val;scanf("%d", &val);  // 输入当前节点的值,-1表示空节点if (val == -1){return NULL;}else {struct TreeNode* root = (struct TreeNode*)malloc(sizeof(struct TreeNode));root->val = val;root->left = createTree();  // 递归创建左子树root->right = createTree();  // 递归创建右子树return root;}
}void preorderTraversal(struct TreeNode* root) 
{if (root == NULL) return;  // 如果节点为空,返回printf("%d ", root->val);  // 先访问根节点preorderTraversal(root->left);  // 再递归遍历左子树preorderTraversal(root->right);  // 最后递归遍历右子树
}void inorderTraversal(struct TreeNode* root) 
{if (root == NULL) return;  // 如果节点为空,返回inorderTraversal(root->left);  // 先递归遍历左子树printf("%d ", root->val);  // 再访问根节点inorderTraversal(root->right);  // 最后递归遍历右子树
}void postorderTraversal(struct TreeNode* root) 
{if (root == NULL) return;  // 如果节点为空,返回postorderTraversal(root->left);  // 先递归遍历左子树postorderTraversal(root->right);  // 再递归遍历右子树printf("%d ", root->val);  // 最后访问根节点
}int main() 
{// 递归创建二叉树printf("先序输入二叉树(用 -1 代替 NULL):\n");struct TreeNode* root = createTree();// 先序遍历二叉树printf("先序遍历: ");preorderTraversal(root);printf("\n");// 中序遍历二叉树printf("中序遍历: ");inorderTraversal(root);printf("\n");// 后序遍历二叉树printf("后序遍历: ");postorderTraversal(root);printf("\n");// 释放内存free(root);return 0;
}

层序遍历——递归

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <stdlib.h>// 定义二叉树节点
typedef struct TreeNode 
{int val;struct TreeNode* left;struct TreeNode* right;
} TreeNode;// 定义队列节点
typedef struct QueueNode 
{TreeNode* data;struct QueueNode* next;
} QueueNode;// 定义队列
typedef struct Queue 
{QueueNode* front;QueueNode* rear;
} Queue;// 初始化队列
void initQueue(Queue* q) 
{q->front = NULL;q->rear = NULL;
}// 判断队列是否为空
int isQueueEmpty(Queue* q) 
{return (q->front == NULL);
}// 入队
void enqueue(Queue* q, TreeNode* val) 
{QueueNode* newNode = (QueueNode*)malloc(sizeof(QueueNode));newNode->data = val;newNode->next = NULL;if (q->rear == NULL) {q->front = q->rear = newNode;}else {q->rear->next = newNode;q->rear = newNode;}
}// 出队
TreeNode* dequeue(Queue* q) 
{if (isQueueEmpty(q)) {printf("Queue is empty.\n");return NULL;}QueueNode* tempNode = q->front;TreeNode* tempData = q->front->data;q->front = q->front->next;if (q->front == NULL) {q->rear = NULL;}free(tempNode);return tempData;
}// 创建二叉树
TreeNode* createBinaryTree() 
{int val;scanf("%d", &val);if (val == -1) {return NULL;}TreeNode* root = (TreeNode*)malloc(sizeof(TreeNode));root->val = val;root->left = createBinaryTree();root->right = createBinaryTree();return root;
}int getDepth(TreeNode* root)
{if (root == NULL){return 0;}int left_depth = getDepth(root->left);int right_depth = getDepth(root->right);return (left_depth > right_depth) ? (left_depth + 1) : (right_depth + 1);
}void levelOrderHelper(TreeNode* root, int level)
{if (root == NULL){return;}if (level == 1){printf("%d ", root->val);}else if (level > 1){levelOrderHelper(root->left, level - 1);levelOrderHelper(root->right, level - 1);}
}void levelOrder(TreeNode* root)
{int depth = getDepth(root);for (int i = 1; i <= depth; i++){levelOrderHelper(root, i);}
}int main() 
{printf("请输入二叉树节点的值,-1表示空节点:\n");TreeNode* root = createBinaryTree();printf("二叉树层序遍历的结果为:");levelOrder(root);printf("\n");return 0;
}

前中后序遍历——迭代

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <stdlib.h>//链式存储结构
struct TreeNode 
{int val;struct TreeNode* left;struct TreeNode* right;
};struct TreeNode* createTree() 
{int val;scanf("%d", &val);  // 输入当前节点的值,-1表示空节点if (val == -1) {return NULL;}else {struct TreeNode* root = (struct TreeNode*)malloc(sizeof(struct TreeNode));root->val = val;root->left = createTree();  // 递归创建左子树root->right = createTree();  // 递归创建右子树return root;}
}void preorderTraversal(struct TreeNode* root) 
{if (root == NULL) return;struct TreeNode* stack[1000];int top = -1;stack[++top] = root;while (top >= 0) {struct TreeNode* node = stack[top--];printf("%d ", node->val);if (node->right) stack[++top] = node->right;if (node->left) stack[++top] = node->left;}
}/*
1.创建一个栈,将根节点压入栈中。
2.当栈不为空时,弹出栈顶元素,访问该节点。
3.如果该节点的右孩子不为空,将右孩子压入栈中。
4.如果该节点的左孩子不为空,将左孩子压入栈中。
5.重复步骤2到4,直到栈为空。
*/
void inorderTraversal(struct TreeNode* root) 
{/*中序非递归遍历,暂且就让结点1的数据为1,结点2的数据为2...1.首先,node指向结点1,此时栈为[ 1 )。下面开始循环2.node不空,node入栈,循环将node的左结点全部入栈,此时node为NULL,此时栈为[ 1 ,2 )。3.出栈,node结点2,打印出数值2,node再指向结点2的右结点,即NULL,此时栈为[ 1 )。4.top>=0可以执行外循环,node为NULL无法执行第二个循环,此时栈还为[ 1 ) 5.出栈,node指向结点1,打印出数值2,node再指向结点1的右结点,即结点3,此时栈为[ )6.node不为空,可以进行外循环和内循环,node及所有左结点入栈,此时栈为[ 3 )7.出栈,node指向结点3,打印出数值3,node再指向结点3的右结点,即NULL,此时栈为[ )8.栈为 NULL,node也为NULL,完美结束外循环,结束程序*/if (root == NULL) return;struct TreeNode* stack[1000];int top = -1;struct TreeNode* node = root;while (top >= 0 || node) {while (node) {stack[++top] = node;node = node->left;}node = stack[top--];printf("%d ", node->val);node = node->right;}
}
/*
1.如果根节点为空,直接返回;
2.初始化栈,并将根节点入栈;
3.只要栈不为空,就一直执行以下操作:a. 将当前节点的所有左子节点都入栈,直到左子树为空;b. 取出栈顶元素,输出其值,并将当前节点指向其右子节点;c. 如果右子节点不为空,将其入栈。
*///后序遍历法二
void postorderTraversal(struct TreeNode* root) {if (root == NULL) return;struct TreeNode* stack1[1000];struct TreeNode* stack2[1000];int top1 = -1, top2 = -1;stack1[++top1] = root;while (top1 >= 0) {struct TreeNode* node = stack1[top1--];stack2[++top2] = node;if (node->left) stack1[++top1] = node->left;if (node->right) stack1[++top1] = node->right;}while (top2 >= 0) {struct TreeNode* node = stack2[top2--];printf("%d ", node->val);}
}/*
它使用了两个栈来实现:
第一个栈用来辅助遍历树的节点;
第二个栈用来按后序遍历的顺序存储节点。1.从根节点开始,依次将左子树的节点入栈;
2.弹出栈顶节点,将其入第二个栈;
3.再依次将右子树的节点入第一个栈;
4.重复步骤 2 和步骤 3,直到第一个栈为空;
5.最后依次弹出第二个栈的节点,并输出它们的值。
*/
int main() 
{// 递归创建二叉树printf("请输入二叉树(用 -1 表示 NULL):\n");struct TreeNode* root = createTree();// 先序遍历二叉树printf("先序遍历: ");preorderTraversal(root);printf("\n");// 中序遍历二叉树printf("中序遍历: ");inorderTraversal(root);printf("\n");// 后序遍历二叉树printf("后序遍历: ");postorderTraversal(root);printf("\n");// 释放内存free(root);return 0;
}
/*
可以测试输入( 1 2 -1 -1 3 -1 -1 )
构建成如下二叉树1/    \2       3/ \     / \-1  -1  -1  -1*/

层序遍历——迭代

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <stdlib.h>// 定义二叉树节点
typedef struct TreeNode 
{int val;struct TreeNode* left;struct TreeNode* right;
} TreeNode;// 定义队列节点
typedef struct QueueNode 
{TreeNode* data;struct QueueNode* next;
} QueueNode;// 定义队列
typedef struct Queue 
{QueueNode* front;QueueNode* rear;
} Queue;// 初始化队列
void initQueue(Queue* q) 
{q->front = NULL;q->rear = NULL;
}// 判断队列是否为空
int isQueueEmpty(Queue* q) 
{return (q->front == NULL);
}// 入队
void enqueue(Queue* q, TreeNode* val) 
{QueueNode* newNode = (QueueNode*)malloc(sizeof(QueueNode));newNode->data = val;newNode->next = NULL;if (q->rear == NULL) {q->front = q->rear = newNode;}else {q->rear->next = newNode;q->rear = newNode;}
}// 出队
TreeNode* dequeue(Queue* q) 
{if (isQueueEmpty(q)) {printf("Queue is empty.\n");return NULL;}QueueNode* tempNode = q->front;TreeNode* tempData = q->front->data;q->front = q->front->next;if (q->front == NULL) {q->rear = NULL;}free(tempNode);return tempData;
}// 创建二叉树
TreeNode* createBinaryTree() 
{int val;scanf("%d", &val);if (val == -1) {return NULL;}TreeNode* root = (TreeNode*)malloc(sizeof(TreeNode));root->val = val;root->left = createBinaryTree();root->right = createBinaryTree();return root;
}// 层序遍历
void levelOrder(TreeNode* root) 
{Queue q;initQueue(&q);enqueue(&q, root);while (!isQueueEmpty(&q)) {TreeNode* node = dequeue(&q);printf("%d ", node->val);if (node->left) {enqueue(&q, node->left);}if (node->right) {enqueue(&q, node->right);}}
}
/*
将根结点入队,队不空:出栈,打印左结点不空,将左结点入栈右结点不空,将右结点入栈
*/int main() 
{printf("请输入二叉树节点的值,-1表示空节点:\n");TreeNode* root = createBinaryTree();printf("二叉树层序遍历的结果为:");levelOrder(root);printf("\n");return 0;
}

写在最后

又到了最后的环节,二叉树的遍历在力扣上也有练手的题目:

144. 二叉树的前序遍历 - 力扣(LeetCode)——简单

94. 二叉树的中序遍历 - 力扣(LeetCode)——简单

145. 二叉树的后序遍历 - 力扣(LeetCode)——简单

102. 二叉树的层序遍历 - 力扣(LeetCode)——中等

👍🏻 点赞,你的认可是我创作的动力!
收藏,你的青睐是我努力的方向!
✏️ 评论,你的意见是我进步的财富!

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

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

相关文章

Ceres的自动求导实现原理剖析

目录数学原理实现原理总结首先注意数值求导和自动求导在使用的时候的不同之处。 实际上&#xff0c;正是自动求导这个地方使用了类模板&#xff0c;导致它不仅可以传入参数&#xff0c;还可以传入Jet类型的数据&#xff0c;从而实现了参数的雅可比矩阵的计算&#xff0c;完成自…

TPM密钥管理、使用

前面讲过证书相关内容&#xff0c;除了在软件方面有所应用外&#xff0c;在硬件方面也有很多应用。本次讲一下TPM相关的内容。 一、TPM介绍 1.1背景 TCG基于硬件安全的架构是为应对1990s后期日益增多的复杂恶意软件攻击应用而生的。当时以及现在&#xff0c;抵御PC客户端网络…

树状数组(高级数据结构)-蓝桥杯

一、简介树状数组 (Binary Indexed Tree,BIT)&#xff0c;利用数的二进制特征进行检索的一种树状结构。一种真正的高级数据结构&#xff1a; 二分思想、二叉树、位运算、前缀和。高效!代码极其简洁!二、基本应用数列a1,a2,....,an&#xff0c;操作&#xff1a;单点修改&#xf…

详解HashMap

目录 1.hash code 2.数据结构 3.初始化 4.存取 4.1.put 4.2.get 5.迭代 6.扩容 7.JDK1.7版本存在的问题 7.1.性能跌落 7.2.循环链表 8.散列运算 9.扰动函数 1.hash code hash code是使用hash函数运算得到的一个值&#xff0c;是对象的身份证号码&#xff0c;用于…

OpenSumi 是信创开发云的首选

原文作者&#xff1a;行云创新技术总监 邓冰寒 引言 随着云原生应用的日益普及&#xff0c;开发上云也逐步被越来越多的厂商和开发者接受&#xff0c;在这个赛道国内外有不少玩家&#xff0c;国外的 GitHub Codespaces、CodeSandbox&#xff0c;GitPod、亚马逊 Cloud9&#xf…

借力英特尔® Smart Edge,灵雀云 ACP 5G 专网解决方案获得多维度优化加速

近日&#xff0c;灵雀云联合英特尔推出了集成Smart Edge 模块的灵雀云 ACP 5G 专网解决方案&#xff0c;同时共同发布了《借力英特尔 Smart Edge&#xff0c;基于云原生解决方案的灵雀云 ACP 5G 专网版本获得多维度优化加速》白皮书。 得益于云计算技术和 5G 网络的高速发展&am…

Win10 环境 安卓ollvm编译与配置 ndk代码混淆加密

确定你正在使用的ndk版本 查看build.gradle ndkVersion 21.4.7075529 确定你使用的ndk的ollvm版本 C:\Users\Administrator\AppData\Local\Android\Sdk\ndk\21.4.7075529\toolchains\llvm\prebuilt\windows-x86_64\bin\llvm-config.exe --version 9.0.9svn 确定了ollvm版本后…

动手学深度学习(第二版)学习笔记 第二章

官网&#xff1a;http://zh.d2l.ai/ 视频可以去b站找 记录的是个人觉得不太熟的知识 第二章 预备知识 代码地址&#xff1a;d2l-zh/pytorch/chapter_preliminaries 2.1 数据操作 2.1. 数据操作 — 动手学深度学习 2.0.0 documentation 如果只想知道张量中元素的总数&#…

GIT分支管理策略

git基本操作git操作的前提条件:本地windows安装git学习idea中的插件使用idea的git基本操作:远程仓库remote更新fetch:git fetch拉取pull: git pull上传push: git push合并merge: git merge 合并分支本地提交commit:git commit分支branch: git branch 查看分支或者 切换分支上述…

软件设计(十四)-UML建模(上)

软件设计&#xff08;十三&#xff09;-原码、反码、补码、移码https://blog.csdn.net/ke1ying/article/details/129115844?spm1001.2014.3001.5501 UML建模包含&#xff1a;用例图&#xff0c;类图与对象图&#xff0c;顺序图&#xff0c;活动图&#xff0c;状态图&#xff…

web网页如何实现响应式导航栏--移动端导航栏

背景&#xff1a; 一提到响应式导航栏&#xff0c;大家第一反应可能就是bootstrap响应式导航栏&#xff0c;这个响应式的一般是针对屏幕变小时&#xff0c;视口出现导航栏&#xff0c;可是&#xff0c;展示到移动端的时候&#xff0c;并没有变化&#xff1f;&#xff1f;&#…

京东测试进阶之路:初入测试碎碎念篇

1、基本的测试用例设计方法 基本的测试用例设计方法&#xff08;边界值分析、等价类划分等&#xff09;。 业务和场景的积累&#xff0c;了解测试需求以及易出现的bug的地方。 多维角度设计测试用例&#xff08;用户、业务流程、异常场景、代码逻辑&#xff09;。 2、需求分析 …

ccc-pytorch-基础操作(2)

文章目录1.类型判断isinstance2.Dimension实例3.Tensor常用操作4.索引和切片5.Tensor维度变换6.Broadcast自动扩展7.合并与分割8.基本运算9.统计属性10.高阶OP大伙都这么聪明&#xff0c;注释就只写最关键的咯1.类型判断isinstance 常见类型如下&#xff1a; a torch.randn(…

虹科新闻 | 虹科与b-plus正式建立合作伙伴关系,共同致力于用于ADAS/AD系统开发的VV测量解决方案

虹科b-plus 携手共创未来&#xff01; 近期&#xff0c;虹科与德国b-plus正式建立合作伙伴关系。未来&#xff0c;虹科与b-plus将共同致力于提供用于ADAS/AD系统开发的V&V测量解决方案。 合作寄语 虹科CEO陈秋苑女士表示&#xff1a;“虹科非常期待与b-plus合作&#x…

Microsoft Dynamics 365:导入License到服务层,通过Business Central Administration Shell

本文主要是Microsoft Dynamics 365的License导入的图解干货&#xff0c;不多赘述&#xff0c;直接上图&#xff1a;第一步&#xff1a;准备好的License文件放在你喜欢的目录下第二步&#xff1a;到开始程序里找到并打开 Business Central Administration Shell3.第三步&#xf…

Day895.MySql误删数据还原方案 -MySQL实战

MySql误删数据还原方案 Hi&#xff0c;我是阿昌&#xff0c;今天学习记录的是关于MySql误删数据还原方案的内容。 传统的高可用架构是不能预防误删数据的&#xff0c;因为主库的一个 drop table 命令&#xff0c;会通过 binlog 传给所有从库和级联从库&#xff0c;进而导致整…

ASE20N60-ASEMI的MOS管ASE20N60

编辑-Z ASE20N60在TO-247封装里的静态漏极源导通电阻&#xff08;RDS(ON)&#xff09;为0.4Ω&#xff0c;是一款N沟道高压MOS管。ASE20N60的最大脉冲正向电流ISM为80A&#xff0c;零栅极电压漏极电流(IDSS)为10uA&#xff0c;其工作时耐温度范围为-55~150摄氏度。ASE20N60功耗…

UVM实战--加法器

前言 这里以UVM实战&#xff08;张强&#xff09;第二章为基础修改原有的DUT&#xff0c;将DUT修改为加法器&#xff0c;从而修改代码以使得更加深入的了解各个组件的类型和使用。 一. 组件的基本框架 和第二章的平台的主要区别点 &#xff08;1&#xff09;有两个transactio…

我的三周年创作纪念日——学习不止,创作不停

机缘 最开始写文章博客&#xff0c;是为了用输出倒逼自己输入。 从校园离开后&#xff0c;才逐渐意识到学习的不容易。没有写好的教材课程、没有画好的考点重点&#xff0c;没有一起学习的同学&#xff0c;更没有明确的学习方向和路径。 数据分析方向可以学的东西太多了&…

P18 PyTorch 感知机的梯度推导

前言这里面简单介绍一下单层感知机和多层感知机的模型参考&#xff1a;https://www.bilibili.com/video/BV17e4y1q7NG?p41一 单层感知机模型输入: k 代表网络层数&#xff0c;i 代表输入节点的编号前向传播: 权重系数k: 层数i: 前一层输入节点编号j: 当前层输出节点编号这里&a…