[LeetCode] 二叉树 I — 深度优先遍历(前中后序遍历) | 广度优先遍历(层序遍历):递归法迭代法
二叉树
- 基础知识
- 深度优先遍历
- 递归法
- 迭代法(栈)
- 144# 二叉树的前序遍历
- 94# 二叉树的中序遍历
- 145# 二叉树的后序遍历
- 广度优先遍历
- 递归法
- 迭代法(队列)
- 102# 二叉树的层序遍历
- 107# 二叉树的层序遍历 II
- 199# 二叉树的右视图
- 637# 二叉树的层平均值
- 429# N叉树的层序遍历
- 515# 在每个树行中找最大值
- 116# 填充每个节点的下一个右侧节点指针
- 117# 填充每个节点的下一个右侧节点指针 II
- 104# 二叉树的最大深度
- 111# 二叉树的最小深度
- 补充知识:递归
- 汉诺塔
基础知识
存储方式:数组顺序存储 / 指针链式存储
顺序存储:节点i的左孩子2i+1 、右孩子2i+2、父节点(i-1)/2
链式存储:
struct TreeNode {int val;TreeNode *left;TreeNode *right;TreeNode(int x) : val(x), left(NULL), right(NULL) { }
}
完全二叉树:除底层外每层节点数都达到最大,底层节点集中在左边,包括满二叉树
满二叉树:深度为k的满二叉树有2^k-1个节点(1 2 ... 2^(k-1))
二叉搜索树:有序树,左子树<根节点<右子树,查找、插入、删除时间复杂度均为 O(logn),最坏情况为O(n)
平衡二叉树:左右子树的高度差(平衡因子)不超过1,避免树的高度过大以确保操作的时间复杂度稳定在 O(logn)
平衡二叉搜索树:AVL树、红黑树、Treap
AVL 树
- 严格平衡(平衡因子 ≤ 1)
- 优点:查询效率极高(严格 O(logn))
- 缺点:插入/删除可能需要频繁旋转,维护成本高
红黑树
- 近似平衡(最长路径不超过最短路径的 2 倍)
- 优点:插入/删除性能更优,适合频繁修改的场景
- 应用:C++
std::map、JavaTreeMap、数据库索引Treap
- 结合二叉搜索树和堆的性质,通过随机优先级维护平衡
深度优先遍历 借助栈实现
-
前序遍历:中左右
-
中序遍历:左中右
-
后序遍历:左右中
广度优先遍历 借助队列实现
- 层次遍历:逐层从左到右访问所有节点
深度优先遍历
递归法
// 前序遍历
void preorder(TreeNode *root, vector<int> &vec) {if (root == nullptr) return;vec.push_back(root->val);preorder(root->left, vec);preorder(root->right, vec);
}
// 中序遍历
void inorder(TreeNode *root, vector<int> &vec) {if (root == nullptr) return;inorder(root->left, vec);vec.push_back(root->val);inorder(root->right, vec);
}
// 后序遍历
void postorder(TreeNode *root, vector<int> &vec) {if (root == nullptr) return;postorder(root->left, vec);postorder(root->right, vec);vec.push_back(root->val);
}
迭代法(栈)
沿着递归实现依靠调用栈的思想,利用栈实现前中后序遍历
// 前序遍历:中入出右左入出-->中左右
vector<int> preorderTraversal(TreeNode* root) {vector<int> result;stack<TreeNode*> st;if (root == nullptr) return result;st.push(root);while (!st.empty()) {TreeNode* node = st.top();st.pop();result.push_back(node->val);if (node->right) st.push(node->right);if (node->left) st.push(node->left);}return result;
}
// 中序遍历
vector<int> inorderTraversal(TreeNode* root) {vector<int> result;stack<TreeNode*> st;TreeNode *cur = root;while (cur != nullptr || !st.empty()) {if (cur != nullptr) { // 深度遍历左子节点st.push(cur);cur = cur->left;} else {cur = st.top();result.push_back(cur->val);st.pop();cur = cur->right; // 访问根节点并弹出后再访问右子节点}}return result;
}
// 后序遍历:中入出左右入出-->中右左--reverse-->左右中
vector<int> postorderTraversal(TreeNode* root) {vector<int> result;stack<TreeNode*> st;if (root == nullptr) return result;st.push(root);while (!st.empty()) {TreeNode *node = st.top();result.push_back(node->val);st.pop();if (node->left) st.push(node->left);if (node->right) st.push(node->right);}reverse(result.begin(), result.end());return result;
}
以上三种遍历方法并不统一,前后序遍历用栈遍历,而中序遍历用指针遍历,因为栈无法解决访问节点和处理节点不一致的情况
通过为节点作标记统一迭代法:1. 空指针标记法;2. boolean标记法
// 中序遍历--空指针标记法
vector<int> inorderTraversal(TreeNode* root) {vector<int> result;stack<TreeNode*> st;if (root == nullptr) return result;st.push(root);while (!st.empty()) {TreeNode* node = st.top();st.pop();if (node != nullptr) { // 检查空指针标记,右中左顺序入栈if (node->right) st.push(node->right);st.push(node);st.push(nullptr);if (node->left) st.push(node->left);} else {node = st.top();result.push_back(node->val);st.pop();}}return result;
}
// 中序遍历--boolean标记法
vector<int> inorderTraversal(TreeNode* root) {vector<int> result;stack<pair<TreeNode*, bool>> st;if (root == nullptr) return result;st.push(make_pair(root, false));while (!st.empty()) {auto node = st.top().first;auto visited = st.top().second;st.pop();if (!visited) { // 检查boolean标记,右中左顺序入栈if (node->right) st.push(make_pair(node->right, false));st.push(make_pair(node, true));if (node->left) st.push(make_pair(node->left, false));} else {result.push_back(node->val);}}return result;
}
144# 二叉树的前序遍历
给你二叉树的根节点
root,返回它节点值的 前序 遍历。示例 1:
**输入:**root = [1,null,2,3]
输出:[1,2,3]
解释:
![]()
示例 2:
**输入:**root = [1,2,3,4,5,null,8,null,null,6,7,9]
输出:[1,2,4,5,6,7,3,8,9]
解释:
![]()
示例 3:
**输入:**root = []
输出:[]
示例 4:
**输入:**root = [1]
输出:[1]
提示:
- 树中节点数目在范围
[0, 100]内-100 <= Node.val <= 100
// 递归法
// O(n) 0ms; O(n) 10.84MB
/*** Definition for a binary tree node.* struct TreeNode {* int val;* TreeNode *left;* TreeNode *right;* TreeNode() : val(0), left(nullptr), right(nullptr) {}* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}* };*/
class Solution {
public:void preorder(TreeNode *root, vector<int> &vec) {if (root == nullptr) return;vec.push_back(root->val);preorder(root->left, vec);preorder(root->right, vec);}vector<int> preorderTraversal(TreeNode* root) {vector<int> result;preorder(root, result);return result;}
};
空间复杂度 O(n)为递归过程中栈的开销,平均情况下为 O(logn),最坏情况下树呈现链状为O(n)
迭代法:先将根节点入栈,根节点出栈后使其右子节点和左子节点入栈(中入出右左入出–>中左右)
// 迭代法--栈
// O(n) 0ms; O(n) 10.8MB
class Solution {
public:vector<int> preorderTraversal(TreeNode* root) {vector<int> result;stack<TreeNode*> st;if (root == nullptr) return result;st.push(root);while (!st.empty()) {TreeNode* node = st.top();st.pop();result.push_back(node->val);if (node->right) st.push(node->right);if (node->left) st.push(node->left);}return result;}
};
94# 二叉树的中序遍历
给定一个二叉树的根节点
root,返回 它的 中序 遍历 。示例 1:
![]()
输入:root = [1,null,2,3] 输出:[1,3,2]示例 2:
输入:root = [] 输出:[]示例 3:
输入:root = [1] 输出:[1]提示:
- 树中节点数目在范围
[0, 100]内-100 <= Node.val <= 100
// 递归法
// O(n) 0ms; O(n) 10.71MB
/*** Definition for a binary tree node.* struct TreeNode {* int val;* TreeNode *left;* TreeNode *right;* TreeNode() : val(0), left(nullptr), right(nullptr) {}* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}* };*/
class Solution {
public:void inorder(TreeNode *root, vector<int> &vec) {if (root == nullptr) return;inorder(root->left, vec);vec.push_back(root->val);inorder(root->right, vec);}vector<int> inorderTraversal(TreeNode* root) {vector<int> vec;inorder(root, vec);return vec;}
};
// 迭代法--栈
// O(n) 0ms; O(n) 10.79MB
class Solution {
public:vector<int> inorderTraversal(TreeNode* root) {vector<int> result;stack<TreeNode*> st;TreeNode *cur = root;while (cur != nullptr || !st.empty()) {if (cur != nullptr) { // 深度遍历左子节点st.push(cur);cur = cur->left;} else {cur = st.top();result.push_back(cur->val);st.pop();cur = cur->right; // 访问根节点并弹出后再访问右子节点}}return result;}
};
145# 二叉树的后序遍历
给你一棵二叉树的根节点
root,返回其节点值的 后序遍历 。示例 1:
**输入:**root = [1,null,2,3]
输出:[3,2,1]
解释:
![]()
示例 2:
**输入:**root = [1,2,3,4,5,null,8,null,null,6,7,9]
输出:[4,6,7,5,2,9,8,3,1]
解释:
![]()
示例 3:
**输入:**root = []
输出:[]
示例 4:
**输入:**root = [1]
输出:[1]
提示:
- 树中节点的数目在范围
[0, 100]内-100 <= Node.val <= 100
// 递归法
// O(n) 0ms; O(n) 10.73MB
/*** Definition for a binary tree node.* struct TreeNode {* int val;* TreeNode *left;* TreeNode *right;* TreeNode() : val(0), left(nullptr), right(nullptr) {}* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}* };*/
class Solution {
public:void postorder(TreeNode *root, vector<int> &vec) {if (root == nullptr) return;postorder(root->left, vec);postorder(root->right, vec);vec.push_back(root->val);}vector<int> postorderTraversal(TreeNode* root) {vector<int> vec;postorder(root, vec);return vec;}
};
迭代法:利用前序遍历迭代法 中入出右左入出–>中左右 的方法,这里 中入出左右入出–>中右左–reverse–>左右中
// 迭代法--栈
// O(n) 0ms; O(n) 10.87MB
class Solution {
public:vector<int> postorderTraversal(TreeNode* root) {vector<int> result;stack<TreeNode*> st;if (root == nullptr) return result;st.push(root);while (!st.empty()) {TreeNode *node = st.top();result.push_back(node->val);st.pop();if (node->left) st.push(node->left);if (node->right) st.push(node->right);}reverse(result.begin(), result.end());return result;}
};
广度优先遍历
递归法
void order(TreeNode *root, vector<vector<int>> &vec, int depth) {if (root == nullptr) return;if (vec.size() == depth) vec.push_back(vector<int>());vec[depth].push_back(root->val);order(root->left, vec, depth + 1);order(root->right, vec, depth + 1);
}
迭代法(队列)
vector<vector<int>> levelOrder(TreeNode* root) {vector<vector<int>> result;queue<TreeNode*> que;if (root == nullptr) return result;que.push(root);while (!que.empty()) { // 以层为单位遍历,size确定当前层需要处理的节点数int size = que.size();vector<int> vec;for (int i = 0; i < size; i++){TreeNode *cur = que.front();que.pop();vec.push_back(cur->val);if (cur->left) que.push(cur->left);if (cur->right) que.push(cur->right);}result.push_back(vec);}return result;
}
102# 二叉树的层序遍历
给你二叉树的根节点
root,返回其节点值的 层序遍历 。 (即逐层地,从左到右访问所有节点)。示例 1:
![]()
输入:root = [3,9,20,null,null,15,7] 输出:[[3],[9,20],[15,7]]示例 2:
输入:root = [1] 输出:[[1]]示例 3:
输入:root = [] 输出:[]提示:
- 树中节点数目在范围
[0, 2000]内-1000 <= Node.val <= 1000
// 递归法
// O(n) 0ms; O(n) 16.77MB
class Solution {
public:void order(TreeNode *root, vector<vector<int>> &vec, int depth) {if (root == nullptr) return;if (vec.size() == depth) vec.push_back(vector<int>());vec[depth].push_back(root->val);order(root->left, vec, depth + 1);order(root->right, vec, depth + 1);}vector<vector<int>> levelOrder(TreeNode* root) {vector<vector<int>> result;int depth = 0;order(root, result, depth);return result;}
};
// 迭代法--队列
// O(n) 0ms; O(n) 16.89MB
/*** Definition for a binary tree node.* struct TreeNode {* int val;* TreeNode *left;* TreeNode *right;* TreeNode() : val(0), left(nullptr), right(nullptr) {}* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}* };*/
class Solution {
public:vector<vector<int>> levelOrder(TreeNode* root) {vector<vector<int>> result;queue<TreeNode*> que;if (root == nullptr) return result;que.push(root);while (!que.empty()) { // 以层为单位遍历,size确定当前层需要处理的节点数int size = que.size();vector<int> vec;for (int i = 0; i < size; i++){TreeNode *cur = que.front();que.pop();vec.push_back(cur->val);if (cur->left) que.push(cur->left);if (cur->right) que.push(cur->right);}result.push_back(vec);}return result;}
};
107# 二叉树的层序遍历 II
题目链接
层序遍历后反转
// 迭代法--队列
// O(n) 3ms; O(n) 15.70MB
class Solution {
public:vector<vector<int>> levelOrderBottom(TreeNode* root) {vector<vector<int>> result;queue<TreeNode*> que;if (root == nullptr) return result;que.push(root);while (!que.empty()) {vector<int> vec;int size = que.size();for (int i = 0; i < size; i++) {TreeNode *cur = que.front(); vec.push_back(cur->val);que.pop();if (cur->left) que.push(cur->left);if (cur->right) que.push(cur->right);}result.push_back(vec);}reverse(result.begin(), result.end()); // 默认只反转第一维度的元素顺序return result;}
};
199# 二叉树的右视图
题目链接
从右侧所能看到的节点正好是层序遍历中的最后一个节点
// 层序遍历
// O(n) 3ms; O(n) 14.77MB
class Solution {
public:vector<int> rightSideView(TreeNode* root) {vector<int> result;queue<TreeNode*> que;if (root == nullptr) return result;que.push(root);while (!que.empty()) {int size = que.size();for (int i = 0; i < size; i++) {TreeNode *cur = que.front();if (i == size - 1) result.push_back(cur->val);que.pop();if (cur->left) que.push(cur->left);if (cur->right) que.push(cur->right);}}return result;}
};
637# 二叉树的层平均值
题目链接
// 层序遍历
// O(n) 0ms; O(n) 23.39MB
class Solution {
public:vector<double> averageOfLevels(TreeNode* root) {vector<double> result;queue<TreeNode*> que;if (root == nullptr) return result;que.push(root);while (!que.empty()) {int size = que.size();double sum = 0;for (int i = 0; i < size; i++) {TreeNode *cur = que.front();que.pop();sum += cur->val;if (cur->left) que.push(cur->left);if (cur->right) que.push(cur->right);}result.push_back(sum / size);}return result;}
};
429# N叉树的层序遍历
题目链接
// 迭代法--队列
// O(n) 14ms; O(n) 15.7MB
/*
// Definition for a Node.
class Node {
public:int val;vector<Node*> children;Node() {}Node(int _val) {val = _val;}Node(int _val, vector<Node*> _children) {val = _val;children = _children;}
};
*/class Solution {
public:vector<vector<int>> levelOrder(Node* root) {vector<vector<int>> result;queue<Node*> que;if (root == nullptr) return result;que.push(root);while (!que.empty()) {vector<int> vec;int size = que.size();for (int i = 0; i < size; i++) {Node *cur = que.front();vec.push_back(cur->val);que.pop();for (Node *child : cur->children) que.push(child);}result.push_back(vec);}return result;}
};
515# 在每个树行中找最大值
题目链接
// 层序遍历
// O(n) 0ms; O(n) 22.41MB
class Solution {
public:vector<int> largestValues(TreeNode* root) {vector<int> result;queue<TreeNode*> que;if (root == nullptr) return result;que.push(root);while (!que.empty()) {int size = que.size();int max = INT_MIN;for (int i = 0; i < size; i++) {TreeNode *cur = que.front();max = max > cur->val ? max : cur->val;que.pop();if (cur->left) que.push(cur->left);if (cur->right) que.push(cur->right);}result.push_back(max);}return result;}
};
116# 填充每个节点的下一个右侧节点指针
题目链接
// 层序遍历
// O(n) 16ms; O(n) 19.0MB
/*
// Definition for a Node.
class Node {
public:int val;Node* left;Node* right;Node* next;Node() : val(0), left(NULL), right(NULL), next(NULL) {}Node(int _val) : val(_val), left(NULL), right(NULL), next(NULL) {}Node(int _val, Node* _left, Node* _right, Node* _next): val(_val), left(_left), right(_right), next(_next) {}
};
*/class Solution {
public:Node* connect(Node* root) {queue<Node*> que;if (root == nullptr) return root;que.push(root);while (!que.empty()) {int size = que.size();for (int i = 0; i < size; i++) {Node *cur = que.front();que.pop();if (i == size - 1) cur->next = nullptr;else cur->next = que.front();if (cur->left) que.push(cur->left);if (cur->right) que.push(cur->right);}}return root;}
};
117# 填充每个节点的下一个右侧节点指针 II
题目链接
与上题代码相同(是否为完美二叉树不影响代码逻辑)
// 层序遍历
// O(n) 7ms; O(n) 18.52MB
class Solution {
public:Node* connect(Node* root) {queue<Node*> que;if (root == nullptr) return root;que.push(root);while (!que.empty()) {int size = que.size();for (int i = 0; i < size; i++) {Node *cur = que.front();que.pop();if (i == size - 1) cur->next = nullptr;else cur->next = que.front();if (cur->left) que.push(cur->left);if (cur->right) que.push(cur->right);}}return root;}
};
104# 二叉树的最大深度
题目链接
// 递归法
// O(n) 0ms; O(n) 18.61MB
class Solution {
public:int maxDepth(TreeNode* root) {if (root == nullptr) return 0;return max(maxDepth(root->left), maxDepth(root->right)) + 1;}
};
// 层序遍历
// O(n) 0ms; O(n) 18.68MB
class Solution {
public:int maxDepth(TreeNode* root) {int depth = 0;queue<TreeNode*> que;if (root == nullptr) return depth;que.push(root);while (!que.empty()) {int size = que.size();depth++;for (int i = 0; i < size; i++) {TreeNode *cur = que.front();que.pop();if (cur->left) que.push(cur->left);if (cur->right) que.push(cur->right);}}return depth;}
};
111# 二叉树的最小深度
题目链接
注意:叶子节点需要左右孩子都为空
// 层序遍历
// O(n) 0ms; O(n) 143.41MB
class Solution {
public:int minDepth(TreeNode* root) {int depth = 0;queue<TreeNode*> que;if (root == nullptr) return depth;que.push(root);while (!que.empty()) {int size = que.size();depth++;for (int i = 0; i < size; i++) {TreeNode *cur = que.front();que.pop();if (!cur->left && !cur->right) return depth;if (cur->left) que.push(cur->left);if (cur->right) que.push(cur->right);}}return depth;}
};
补充知识:递归
推荐教学视频:快速掌握递归
- 确定问题,即函数参数和返回值
- 解决基准问题,确定终止条件
- 拆解问题,寻找规模更小的子问题,确定单层递归逻辑
每一次递归调用都会把函数的局部变量、参数值和返回地址等压入调用栈中
栈溢出,系统输出的异常是Segmentation fault,考虑是否是无限递归导致
汉诺塔
void hanoi(int n, char F, char A, char T) {if (n = 1) {printf("move %d from %c to %c\n", n, F, T);return;}hanoi(n-1, F, T, A);printf("move %d from %c to %c\n", n, F, T);hanoi(n-1, A, F, T);
}
本文参考 LeetCode官方题解 及 代码随想录
相关文章:
[LeetCode] 二叉树 I — 深度优先遍历(前中后序遍历) | 广度优先遍历(层序遍历):递归法迭代法
二叉树 基础知识深度优先遍历递归法迭代法(栈)144# 二叉树的前序遍历94# 二叉树的中序遍历145# 二叉树的后序遍历 广度优先遍历递归法迭代法(队列)102# 二叉树的层序遍历107# 二叉树的层序遍历 II199# 二叉树的右视图637# 二叉树的…...
主动管理的基本概念
什么是主动管理? 主动管理,又称主动投资,是一种投资策略,投资组合经理进行特定投资的目的是超越投资基准指数。与被动管理不同,主动管理者依靠分析研究、预测以及自己的判断和经验来决定买入、持有和卖出哪些证券。“…...
Python aiortc API
本研究的主要目的是基于Python aiortc api实现抓取本地设备(摄像机、麦克风)媒体流实现Web端预览。本文章仅仅描述实现思路,索要源码请私信我。 demo-server解耦 原始代码解析 http服务器端 import argparse import asyncio import json…...
OpenCV4,快速入门,第二讲:图像色彩空间转换
文章目录 引言一、色彩空间概述1.1 RGB与HSV的区别1.2 HSV的详细含义cvtColor二、cvtColor函数详解2.1 函数原型2.2 参数说明2.3 使用示例三、imwrite函数详解3.1 函数原型3.2 参数说明3.3 使用示例四、完整示例代码五、应用场景与注意事项5.1 HSV的典型应用5.2 注意事项结语引…...
86.(2)攻防世界 WEB PHP2
之前做过,回顾一遍,详解见下面这篇博客 29.攻防世界PHP2-CSDN博客 既然是代码审计题目,打开后又不显示代码,肯定在文件里 <?php // 首先检查通过 GET 请求传递的名为 "id" 的参数值是否严格等于字符串 "admi…...
【Leetcode 每日一题】90. 子集 II
问题背景 给你一个整数数组 n u m s nums nums,其中可能包含重复元素,请你返回该数组所有可能的 子集(幂集)。 解集 不能 包含重复的子集。返回的解集中,子集可以按 任意顺序 排列。 数据约束 ● 1 ≤ n u m s . …...
RK3588——解决Linux系统触摸屏坐标方向相反问题
问题描述:触摸正常产生中断,但系统上报的触摸坐标不正确,是反向的坐标。 解决办法通过修改设备树添加属性翻转坐标。 注:需确认对应的驱动是否有解析该属性的具体内容,否则仍然无法生效。...
面对全球化的泼天流量,出海企业如何观测多地域网络质量?
作者:俞嵩、白玙 泼天富贵背后,技术挑战接踵而至 随着全球化进程,出海、全球化成为很多 Toc 产品的必经之路,保障不同地域、不同网络环境的一致的用户体验成为全球化应用的不得不面对的问题。在跨运营商、跨地域的网络环境中&am…...
YOLOv11实时目标检测 | 摄像头视频图片文件检测
在上篇文章中YOLO11环境部署 || 从检测到训练https://blog.csdn.net/2301_79442295/article/details/145414103#comments_36164492,我们详细探讨了YOLO11的部署以及推理训练,但是评论区的观众老爷就说了:“博主博主,你这个只能推理…...
PyQt6/PySide6 的 QPushButton 类
QPushButton 是 PyQt6 或 PySide6 库中用于创建按钮控件的类。按钮是用户界面中最常用的控件之一,用于触发特定的动作或事件。QPushButton 提供了丰富的功能和灵活性,使得开发者可以轻松地创建各种类型的按钮。下面我将详细介绍 QPushButton 的主要特性及…...
libdrm移植到arm设备
一、环境资源要求 下载libdrm Index of /libdrm 这边使用的是2.4.114版本,版本太高对meson版本要求也很高,为了省事用apt安装meson就不用太高版本了,1.x版本虽然使用makefile编译方便但是太老,对应用支持不太好。 https://dri…...
自定义序列化数据类型
目录 1. WritableComparable1.1 Writable1.2 Comparable1.3 IntWritable 2. 自定义序列化数据类型RectangleWritable3. 矩形面积计算3.1 Map3.2 Reduce 4. 代码和结果4.1 pom.xml中依赖配置4.2 工具类util4.3 矩形面积计算4.4 结果 参考 本文引用的Apache Hadoop源代码基于Apac…...
【Linux网络编程】:URL(encode),HTTP协议,telnet工具
🎁个人主页:我们的五年 🔍系列专栏:Linux网络编程 🌷追光的人,终会万丈光芒 🎉欢迎大家点赞👍评论📝收藏⭐文章 Linux网络编程笔记: https://mp.csdn…...
C语言基础系列【3】VSCode使用
前面我们提到过VSCode有多么的好用,本文主要介绍如何使用VSCode编译运行C语言代码。 安装 首先去官网(https://code.visualstudio.com/)下载安装包,点击Download for Windows 获取安装包后,一路点击Next就可以。 配…...
学前端框架之前,你需要先理解 MVC
MVC 软件架构设计模式鼎鼎大名,相信你已经听说过了,但你确定自己已经完全理解到 MVC 的精髓了吗? 如果你是新同学,没听过 MVC,那可以到网上搜一些文章来看看,不过你要有心理准备,那些文章大多都…...
Mysql:数据库
Mysql 一、数据库概念?二、MySQL架构三、SQL语句分类四、数据库操作4.1 数据库创建4.2 数据库字符集和校验规则4.3 数据库修改4.4 数据库删除4.4 数据库备份和恢复其他 五、表操作5.1 创建表5.2 修改表5.3 删除表 六、表的增删改查6.1 Create(创建):数据新增1&#…...
python的函数介绍
一.定义和调用函数 1.定义函数 在 Python 中,使用 def 关键字来定义一个函数。函数可以包含参数,也可以包含返回值 基本语法 def function_name(parameters):"""docstring"""# Function bodyreturn resultdef greet(n…...
要完成使用MLflow比较模型运行、选择模型并将其部署到REST API的教程
要完成使用MLflow比较模型运行、选择模型并将其部署到REST API的教程,请按照以下有序步骤操作: 设置环境 导出MLflow跟踪URI:设置环境变量以指向您的MLflow跟踪服务。export MLFLOW_TRACKING_URIyour-organizations-MLflow-server-url 加载数…...
Windows Docker笔记-简介摘录
Docker是一个开源的容器化平台,可以帮助开发人员将应用程序与其依赖项打包在一个独立的容器中,然后在任何安装的Docker的环境中快速、可靠地运行。 几个基本概念和优势: 容器:容器是一个轻量级、独立的运行环境,包含了…...
MVC 文件夹:架构之美与实际应用
MVC 文件夹:架构之美与实际应用 引言 MVC(Model-View-Controller)是一种设计模式,它将应用程序分为三个核心组件:模型(Model)、视图(View)和控制器(Controller)。这种架构模式不仅提高了代码的可维护性和可扩展性,而且使得开发流程更加清晰。本文将深入探讨MVC文…...
AI透明化与全球政治格局的发展:如何避免AI被人为操控
在现代社会,人工智能(AI)已经逐渐渗透到我们的日常生活中,尤其是在社交平台和信息传播领域。虽然AI可以极大地推动社会发展,但也潜藏着被恶意操控的风险。最令人担忧的是,某些势力可能通过操控AI来操控公众…...
ubuntu 网络管理--wpa_supplicant、udhcpc
ubuntu 网络管理--wpa_supplicant 1 介绍wpa_supplicant 无线认证wpa_passphrase 配置工具 NetworkManager 网络管理udhcpc 与 dhclient对比dhclient概述主要功能 udhcpc概述主要功能 2 联系依赖关系配置文件 3 区别4 如何选择5 示例使用 wpa_supplicant 手动连接无线网络使用 …...
熟练掌握Http协议
目录 基本概念请求数据Get请求方式和Post请求方式 响应数据响应状态码 基本概念 Http协议全称超文本传输协议(HyperText Transfer Protocol),是网络通信中应用层的协议,规定了浏览器和web服务器数据传输的格式和规则 Http应用层协议具有以下特点&#…...
C++的 I/O 流
本文把复杂的基类和派生类的作用和关系捋出来,具体的接口请参考相关文档 C的 I/O 流相关的类,继承关系如下图所示 https://zh.cppreference.com/w/cpp/io I / O 的概念:内存和外设进行数据交互称为 I / O ,例如:把数…...
寒假刷题Day22
一、2570. 合并两个二维数组 - 求和法 class Solution { public:vector<vector<int>> mergeArrays(vector<vector<int>>& nums1, vector<vector<int>>& nums2) {int i 0, j 0, n1 nums1.size(), n2 nums2.size();int tmp 0;…...
【PDF多区域识别】如何批量PDF指定多个区域识别改名,基于Windows自带的UWP的文字识别实现方案
海关在对进口货物进行查验时,需要核对报关单上的各项信息。对报关单 PDF 批量指定区域识别改名后,海关工作人员可以更高效地从文件名中获取关键信息,如货物来源地、申报价值等。例如文件名 “[原产国]_[申报价值].pdf”,有助于海关快速筛选重点查验对象,提高查验效率和监管…...
【大数据技术】本机PyCharm远程连接虚拟机Python
本机PyCharm远程连接虚拟机Python 注意:本文需要使用PyCharm专业版。 pycharm-professional-2024.1.4VMware Workstation Pro 16CentOS-Stream-10-latest-x86_64-dvd1.iso写在前面 本文主要介绍如何使用本地PyCharm远程连接虚拟机,运行Python脚本,提高编程效率。 注意: …...
Windows图形界面(GUI)-QT-C/C++ - Qt Combo Box
公开视频 -> 链接点击跳转公开课程博客首页 -> 链接点击跳转博客主页 目录 一、概述 1.1 基本概念 1.2 应用场景对比 二、核心属性详解 2.1 行为控制 2.2 显示配置 三、数据操作与访问 3.1 基础数据管理 3.2 高级数据访问 四、用户交互处理 4.1 信号处…...
数字化转型:概念性名词浅谈(第四讲)
大家好,本篇文章是在新年之际写的,所以在这里先给大家拜个年。 今天要介绍的名词为ETL: ETL,是英文Extract-Transform-Load的缩写,用来描述将数据从来源端经过抽取(extract)、转换(transfor…...
标题:市场波动中的价格趋势分析与策略优化
在市场投资中,价格的波动不仅是常态,更是影响投资决策的关键因素。市场价格的变化受多种因素影响,包括供需关系、政策调整、国际市场动态等。如何理解价格走势,并在其中寻找合适的交易机会,是投资者需要长期研究的课题…...
