数据结构 树1
目录
前言
一,树的引论
二,二叉树
三,二叉树的详细理解
四,二叉搜索树
五,二分法与二叉搜索树的效率
六,二叉搜索树的实现
七,查找最大值和最小值
指针传递 vs 传引用
为什么指针按值传递不会修改 root->left?
查到最值的功能
总结
前言
当我们运用链表,栈,队列等线性数据结构来进行搜索数据的时候,他们的时间复杂度都是O(n),我们不妨做一个小小的测试
假设 我们的一个机器可以做一百万次比较每秒
则我们的机器可以执行10^7比较
也就是每次的比较时间为10^-7秒
以上是我们假设一个机器可以做出查找操作的效率,接下来我们用这个机器放入到日常工作中,我们来看看情况,如今我们的数据量是十分惊人的,有着1亿或者10亿的数据量,我们计算一下这个机器处理10亿个数据的效率,运用链表,栈,队列这种数据结构来进行,时间复杂度为O(n)
计算:10亿个数据,我们最差的为10^10*10^-7=10^3s=16.7min,当然我们如果出现了16.7min,肯定是不行的,因为我们都想快点找到自己的数据,所以我们接下来就讲讲树这个结构
一,树的引论
目前我们所学习了链表,栈,队列这些都是线性结构或者说顺序结构
数据结构的选取
有了这么多的数据结构,我们该怎么选择呢?我们应当考虑以下几个方面
1,我们要选择什么样的数据类型
2,操作的成本
3,内存的消耗
4,数据结构实现的难度
树用于表示一种层次的数据结构
(tree)
树的基本结构介绍
树也可以被称为一个递归的数据结构
(树的基本实现方法就是递归)
这里的子树可以看成递归的深度,这个root为入口
树边的计算
一棵树有N个节点,那么这个树有N-1个节点(图中的每一个线可以表示一个链接或者一个边),除了根节点外,图中的每一个节点都有一个边进行对应
深度与高度
深度
节点到根节点的路径长度
高度 节点到子叶节点的路径长度
7 高度为0,深度为2 5 高度为1,深度为2 13 高度为0,深度为3 总的来说,深度为节点往根节点数,高度为节点往子叶节点数
二,二叉树
二叉树的概念
树上的节点最多只可以有两个子叶节点
(不会超过两个小孩,为左孩和右孩)
我们把我们的树换一个角度思考,换成我们所熟悉的样子来看待问题,这样我们就可以构想出一棵树是如何用我们所学过的知识来转化的,我们树中的孩子节点可以这样设置
struct BstNode {int data;BstNode* left;BstNode* right; };
基于树的应用
1,存储天然具备的层级的数据结构----电脑上面的磁盘驱动器上的文件系统
2,组织数据----在一个结构里面进行快速的查找与删除,二叉搜索树
3,Trie树----用于字典,用于一个动态的拼写检查
三,二叉树的详细理解
树的类型与属性
二叉树的通用属性:二叉搜索树的每一个节点的子节点不可以超过两个节点
严格二叉树: 每一个二叉树的子节点只可以为0个或者2个
完全二叉树:除了最后一层,其他层填满,并且最后一层的节点全部都是向左靠
这个就是一个完全二叉树的例子
完美二叉树:所有层都填满
二叉树里的计算
1,节点的最大数量:2^0+2^1+2^2+……+2^n=2^(n+1)-1
2,n个节点的完美二叉树的高度:n=2^(h+1)+1 h=
-1
3,n个节点的完全二叉树的高度:h=
也就是说时间复杂度为O(
)
4,n个节点的最大高度为(n-1)
所以我们一般把树的高度控制到最小,然后如果只有根节点高度为0,如果没有节点的话就是-1
5,diff=|lhight - rhight| lhight为左子树,rhight为右子树
实现可以用数组也可以用链表
四,二叉搜索树
二叉搜索树是一种可以高效进行搜索和更新的数据结构
之前数据结构的效率
抛问:你该使用什么数据结构进行存储一个可以修改的集合
搜索 插入 删除 类型 O(1) O(1)数组末尾 O(n) 数组 O(n)
O(1)链表头部
O(n) 链表 根据我们的前言可以知道,我们利用这两个类型不用什么好的方法的话,那么时间会花费的非常长,这个时候我们可以考虑用二分法,在两边分别放一个指针,这样我们的时间复杂度就是O(
)了,我们利用这个来看看我们在实际的时候,这个时间复杂度可以减多少呢?
例子
假设我们有2^31的数据量,这个数据量以及超过了20亿的数据量
n=2^31 则时间为31*10^-6秒,这个时间相比较上面那一个以及少量非常多的时间了
二叉树的查找成本为O(
)但是也有很差的情况O(n),但是这种情况是可以避免的,可以利用平衡二叉树
平衡二叉树的概念
平衡二叉树是一种自平衡的二叉搜索树,其中每个节点的左右子树的高度差(平衡因子)不超过1,这意味着树在任何时候都保持相对平衡的状态,避免了二叉树退化为链表的情况,从而确保了操作的时间复杂度
二叉搜索树
核心规则:
左子树的节点值小于当前节点的值
右子树的节点值大于当前节点的值
左右子树本身也必须是二叉搜索树
这个是一个二叉搜索树,我们来详细分析一下
5比7小 9比7大,符合
3比5小,比7小 6比5大,比7小 8比9小,比7大 10比9大,比7小符合
我们看这些是要进行比较的,而不是单单比较5和9,左右子树本身也必须是二叉搜索树
五,二分法与二叉搜索树的效率
我们不妨想想,二分法的时间复杂度是多少呢?如果忘记了二分法也没事,我写了一个很简单的二分法代码
二分法
#include<iostream>using namespace std;int search(int arr[], int sign, int n, int left, int right) {while (left <= right) {int mid = left + (right - left) / 2;if (arr[mid] == sign) {return 1;}else if (arr[mid] > sign) {right = mid - 1;}else {left = mid + 1;}}return -1; }int main() {int arr[9] = { 1,2,3,4,5,6,7,8,9 };int sign = 8;int n = sizeof(arr) / sizeof(arr[0]);int result = search(arr, sign, n, 0, n - 1);if (result == -1) {cout << "未找到" << endl;}else {cout << "找到了" << endl;}return 0; }
我们在使用二分法的时候,都是利用空间减半的方法,n->n/2->n/4->……,最后找到我们所想要的最终元素,如果没有找到则会left>right的情况,这个就可以判断是否要终止程序
n/2^k => 2^k = n => k =
二叉搜索树
其实你可以发现二叉搜索树也利用了这样的原理,我们可以来研究一下
我们要寻找3这个元素, 首先在根部进去进行寻找,然后进行分区,是比7大还是比7小,然后进行对空间的对半分,这不就是二分法么,基于这个思想,我们都很喜欢完美二叉树的出现,为什么呢?这不就是每一次分开的时候,都是对半分,这样效率特别高
我们这里思考了查找,但是我们还要有插入,删除的操作,那我们就需要思考怎么插入或者删除之后,把树平衡起来
六,二叉搜索树的实现
基本实现
#include<iostream>using namespace std;struct BstNode {BstNode* left;int data;BstNode* right; };BstNode* GetNode(int x) {BstNode* newNode = new BstNode();newNode->data = x;newNode->left = NULL;newNode->right = NULL;return newNode; }BstNode* Insert(BstNode* root, int x) {if (root == NULL) {root = GetNode(x);return root;}else if (x > root->data) {Insert(root->right, x);}else if (x < root->data) {Insert(root->left, x);}return root; }bool search(BstNode* root,int x) {if (root == NULL) {return false;}else if (root->data == x) {return true;}else if (root->data >= x) {return search(root->left, x);}else {return search(root->right, x);} }int main() {BstNode* root = NULL;root = Insert(root, 10);root = Insert(root, 6);root = Insert(root, 7);bool key = search(root, 10);if (key == true) {cout << "找到了" << endl;}else {cout << "未找到" << endl;} }
这里是用写了插入和搜索,这个main函数里面一定要用root来接收,因为root在其他地方为形参,改变不了形参,如果不想这么麻烦也可以设置一个全局变量,我们重点来理解一下这个递归,我们理解了插入的递归,这个搜索也是可以迎刃而解
细讲递归操作
BstNode* Insert(BstNode* root, int x) {if (root == NULL) {root = GetNode(x);return root;}else if (x > root->data) {Insert(root->right, x);}else if (x < root->data) {Insert(root->left, x);}return root; }
这里一开始root肯定是为空的,所以我们要给根节点赋予一个节点,然后下一次的时候就是判断这个节点是放到左子树还是右子树,我们这里用递归来进行树的深入
到了下一次,我们就会到左子树还是右子树,注意此时进入递归了,这个root不是你根节点了,是左子树或者右子树的根节点,然后当我找到left或者right为NULL的时候,我可以用第一个if语句给这个节点赋予一个节点了,重中之重此时的root不是根节点,然后赋予完返回根节点
然后进入到上一次的递归进行返回,最终递归逐个破解,返回的是这个树的根节点很好这里讲的是错误的,这是作者初代代码,后面有正确的改进,也可以给读者看看错误的递归思路,确实有点绕,此代码也有细小的问题,读者可以先自己思考哪里错误,后面再看正确的思路
放到堆和栈的策略
这个就涉及大到一个变量的生命周期的问题了,大致就是你想临时的就放到栈里,你想长期的就放到堆里
七,查找最大值和最小值
这个十分的简单哈,真的,你会发现这个最大值不就是最右边的那个么,这个最小值不就是最左边那个么,我们来实现一下
#include<iostream>using namespace std;struct BstNode {BstNode* left;int data;BstNode* right; };BstNode* GetNode(int x) {BstNode* newNode = new BstNode();newNode->data = x;newNode->left = NULL;newNode->right = NULL;return newNode; }BstNode* Insert(BstNode* root, int x) {if (root == NULL) {root = GetNode(x);return root;}else if (x > root->data) {root->right = Insert(root->right, x);}else if (x < root->data) {root->left = Insert(root->left, x);}return root; }bool search(BstNode* root,int x) {if (root == NULL) {return false;}else if (root->data == x) {return true;}else if (root->data >= x) {return search(root->left, x);}else {return search(root->right, x);} }BstNode* MAX(BstNode* root) {if (root == NULL) {cout << "未找到" << endl;return NULL;}BstNode* current = root;while (current -> right != NULL) {current = current->right;}return current; }int main() {BstNode* root = NULL;root = Insert(root, 10);root = Insert(root, 6);root = Insert(root, 7);root = Insert(root, 15);root = Insert(root, 14);root = Insert(root, 20);bool key = search(root, 7);if (key == true) {cout << "找到了" << endl;}else {cout << "未找到" << endl;}cout << MAX(root)->data << endl; }
这里是既有修正的代码和寻找最值的代码,我会一 一讲述
错误的点
BstNode* Insert(BstNode* root, int x) {if (root == NULL) {root = GetNode(x);return root;}else if (x > root->data) {root->right = Insert(root->right, x);}else if (x < root->data) {root->left = Insert(root->left, x);}return root; }
这里为什么不可以利用root = GetNode(x);来给左边和右边进行赋值呢?
假设你插入
6
到如下 BST:10/ \NULL NULL
执行:
root = Insert(root, 6);
Insert(root, 6);
root = 10
6 < 10
,调用Insert(root->left, 6);
Insert(root->left, 6);
root->left == NULL
,进入:if (root == NULL) {root = GetNode(x); // root 现在指向了新节点 6return root; }
- 但
root
是 局部变量,修改root
不会修改root->left,这里不可以进行对于左边的赋值操作
- 这一步返回了新节点
6
,但Insert(root->left, 6);
的返回值被丢弃了,没有赋值给root->left
递归结束后,原来的
root->left
仍然是NULL
,导致插入失败但是又想,奇怪,我传的是指针呀,为什么是值操作嘞?
指针传递 vs 传引用
在 C++ 里,指针本身是 按值传递 的
换句话说,Insert(root->left, x);
传递的root->left
是它的拷贝,而不是原始变量的引用Insert(root->left, x); // 你以为 root->left 会被修改
我觉得
root->left
传递给Insert
后,在Insert
内部的root = GetNode(x);
可以直接修改root->left
实际发生的情况:
void Insert(BstNode* root, int x);
root->left
的值(即NULL
)被传递给Insert
- 进入
Insert(root->left, x);
,这里的root
只是root->left
的拷贝root = GetNode(x);
只是修改了 拷贝的root
,不会修改root->left
- 递归结束后,
root->left
仍然是NULL
为什么指针按值传递不会修改
root->left
?来看一个简单的示例
void ChangePointer(int* ptr) {ptr = new int(10); // 只修改了 ptr 的拷贝 }int main() {int* p = NULL;ChangePointer(p);cout << p << endl; // 还是 NULL,没有变! }
这里的
ChangePointer(p);
不会修改p
,因为p
作为参数传进去时,只是它的拷贝,所以ptr = new int(10);
不会影响外部的p
这里也就是我们很常见的指针问题,我们这放了个形参,但不是全局变量,是局部的,这里确实再堆里面创建了一个节点,但是没有东西接收,所以会为NULL,上面这个简单的例子就阐明了
查到最值的功能
BstNode* MAX(BstNode* root) {if (root == NULL) {cout << "未找到" << endl;return NULL;}BstNode* current = root;while (current -> right != NULL) {current = current->right;}return current; }
我们这里只需要一直往右边就可以找到最大值了
总结
我们总结一下我们所学的东西
1,树的概念和树的基本知识
2,树的高度为节点到子叶的距离,深度为节点到根部的距离
3,二叉树的概念,需注意核心规则
4,二叉树的分类:严格二叉树,完全二叉树,完美二叉树,平衡二叉树
5,二叉树与二分法的关系和两个的具体实现
6,实现的时候遇到了一个bug为指针传递和传引用的区别,两个是不一样的传指针其实也就是一个形参罢了,引用不一样,这个是再原来的地方做法,也就是再常量区,这个需要学过C++才知道
7,查找最值的方法
相关文章:
数据结构 树1
目录 前言 一,树的引论 二,二叉树 三,二叉树的详细理解 四,二叉搜索树 五,二分法与二叉搜索树的效率 六,二叉搜索树的实现 七,查找最大值和最小值 指针传递 vs 传引用 为什么指针按值传递不会修…...
EtherCAT主站IGH-- 25 -- IGH之fsm_slave_scan.h/c文件解析
EtherCAT主站IGH-- 25 -- IGH之fsm_slave_scan.h/c文件解析 0 预览一 该文件功能`fsm_slave_scan.c` 文件功能函数预览二 函数功能介绍`fsm_slave_scan.c` 中主要函数的作用1. `ec_fsm_slave_scan_state_start`2. `ec_fsm_slave_scan_state_address`3. `ec_fsm_slave_scan_stat…...
redis数据安全与性能保障
数据安全与性能保障 1、持久化1.1 快照持久化1.2 AOF持久化1.3 重写/压缩AOF文件 2、复制2.1 Redis复制的启动过程2.2 主从链 3、处理系统故障3.1 验证快照文件和AOF文件 4、事务4.1 java中的redis事务使用 如有侵权,请联系~ 如有错误,也欢迎…...
llama.cpp LLM_CHAT_TEMPLATE_DEEPSEEK_3
llama.cpp LLM_CHAT_TEMPLATE_DEEPSEEK_3 1. LLAMA_VOCAB_PRE_TYPE_DEEPSEEK3_LLM2. static const std::map<std::string, llm_chat_template> LLM_CHAT_TEMPLATES3. LLM_CHAT_TEMPLATE_DEEPSEEK_3References 不宜吹捧中国大语言模型的同时,又去贬低美国大语言…...
【图文详解】lnmp架构搭建Discuz论坛
安装部署LNMP 系统及软件版本信息 软件名称版本nginx1.24.0mysql5.7.41php5.6.27安装nginx 我们对Markdown编辑器进行了一些功能拓展与语法支持,除了标准的Markdown编辑器功能,我们增加了如下几点新功能,帮助你用它写博客: 关闭防火墙 systemctl stop firewalld &&a…...
一文读懂fgc之cms
一文读懂 fgc之cms-实战篇 1. 前言 线上应用运行过程中可能会出现内存使用率较高,甚至达到95仍然不触发fgc的情况,存在内存打满风险,持续触发fgc回收;或者内存占用率较低时触发了fgc,导致某些接口tp99,tp…...
Agent 高频知识汇总:查漏补缺参考大全
Agent 高频问题汇总 一、基础概念类 (一)请解释 Agent 的概念及其主要特点 Agent 是一种能够感知所处环境,并基于感知信息做出决策、采取行动以实现特定目标的实体。它既可以是简单的规则基系统,也能是复杂的智能体,…...
毕业设计--具有车流量检测功能的智能交通灯设计
摘要: 随着21世纪机动车保有量的持续增加,城市交通拥堵已成为一个日益严重的问题。传统的固定绿灯时长方案导致了大量的时间浪费和交通拥堵。为解决这一问题,本文设计了一款智能交通灯系统,利用车流量检测功能和先进的算法实现了…...
fatal error C1083: [特殊字符]ļ: openssl/opensslv.h: No such file or directory
一、环境 1. Visual Studio 2017 2. edk2:202305 3. Python:3.11.4 二、 fatal error C1083: 򿪰ļ: openssl/opensslv.h: No such file or directory 上图出现这个警告,不用管。 出现Done,说明编译成功。 执行上…...
EasyExcel使用详解
文章目录 EasyExcel使用详解一、引言二、环境准备与基础配置1、添加依赖2、定义实体类 三、Excel 读取详解1、基础读取2、自定义监听器3、多 Sheet 处理 四、Excel 写入详解1、基础写入2、动态列与复杂表头3、样式与模板填充 五、总结 EasyExcel使用详解 一、引言 EasyExcel 是…...
论文阅读(十六):利用线性链条件随机场模型检测阵列比较基因组杂交数据的拷贝数变异
1.论文链接:Detection of Copy Number Variations from Array Comparative Genomic Hybridization Data Using Linear-chain Conditional Random Field Models 摘要: 拷贝数变异(CNV)约占人类基因组的12%。除了CNVs在癌症发展中的…...
7.抽象工厂(Abstract Factory)
抽象工厂与工厂方法极其类似,都是绕开new的,但是有些许不同。 动机 在软件系统中,经常面临着“一系列相互依赖的对象”的创建工作;同时,由于需求的变化,往往存在更多系列对象的创建工作。 假设案例 假设…...
从0开始使用面对对象C语言搭建一个基于OLED的图形显示框架(基础组件实现)
目录 基础组件实现 如何将图像和文字显示到OLED上 如何绘制图像 如何绘制文字 如何获取字体? 如何正确的访问字体 如何抽象字体 如何绘制字符串 绘制方案 文本绘制 更加方便的绘制 字体附录 ascii 6x8字体 ascii 8 x 16字体 基础组件实现 我们现在离手…...
负荷预测算法模型
1. 时间序列分析方法 时间序列分析方法是最早被用来进行电力负荷预测的方法之一,它基于历史数据来构建数学模型,以描述时间与负荷值之间的关系。这种方法通常只考虑时间变量,不需要大量的输入数据,因此计算速度快。然而ÿ…...
Flutter Candies 一桶天下
| | | | | | | | 入魔的冬瓜 最近刚入桶的兄弟,有责任心的开发者,对自己的项目会不断进行优化,达到最完美的状态 自定义日历组件 主要功能 支持公历,农历,节气,传统节日,常用节假日 …...
android Camera 的进化
引言 Android 的camera 发展经历了3个阶段 : camera1 -》camera2 -》cameraX。 正文 Camera1 Camera1 的开发中,打开相机,设置参数的过程是同步的,就跟用户实际使用camera的操作步骤一样。但是如果有耗时情况发生时,会…...
HarmonyOS简介:应用开发的机遇、挑战和趋势
问题 更多的智能设备并没有带来更好的全场景体验 连接步骤复杂数据难以互通生态无法共享能力难以协同 主要挑战 针对不同设备上的不同操作系统,重复开发,维护多套版本 多种语言栈,对人员技能要求高 多种开发框架,不同的编程…...
反向代理模块b
1 概念 1.1 反向代理概念 反向代理是指以代理服务器来接收客户端的请求,然后将请求转发给内部网络上的服务器,将从服务器上得到的结果返回给客户端,此时代理服务器对外表现为一个反向代理服务器。 对于客户端来说,反向代理就相当于…...
C++并发:设计基于锁的并发数据结构
(上一篇主要讲了底层逻辑,比较晦涩难懂,这一章讲解数据结构设计) 对于并发场景,数据保护的形式主要如下: 1 采用独立互斥和外部锁 2 专门为并发访问自行设计的数据结构 1 并发设计的内涵 互斥保护数据结…...
数据分析系列--⑥RapidMiner构建决策树(泰坦尼克号案例含数据)
一、资源下载 二、数据处理 1.导入数据 2.数据预处理 三、构建模型 1.构建决策树 2.划分训练集和测试集 3.应用模型 4.结果分析 一、资源下载 点击下载数据集 二、数据处理 1.导入数据 2.数据预处理 三、构建模型 1.构建决策树 虽然决策树已经构建,但对于大多数初学者或…...
leetcode 844 比较含退格的字符串
leetcode 844 比较含退格的字符串 题目描述 给定 s 和 t 两个字符串,当它们分别被输入到空白的文本编辑器后,如果两者相等,返回 true 。# 代表退格字符。 注意:如果对空文本输入退格字符,文本继续为空。 示例 1&#…...
【ArcGIS遇上Python】批量提取多波段影像至单个波段
本案例基于ArcGIS python,将landsat影像的7个波段影像数据,批量提取至单个波段。 相关阅读:【ArcGIS微课1000例】0141:提取多波段影像中的单个波段 文章目录 一、数据准备二、效果比对二、python批处理1. 编写python代码2. 运行代码一、数据准备 实验数据及完整的python位…...
10.6 LangChain提示工程终极指南:从基础模板到动态生成的工业级实践
LangChain提示工程终极指南:从基础模板到动态生成的工业级实践 关键词: LangChain提示模板、动态Prompt生成、少样本学习、结构化输出、Prompt工程 一、Prompt Engineering 的本质:用设计模式重构大模型交互 传统Prompt的局限性: 硬编码文本:修改需求需重构代码缺乏结构…...
DeepSeek-R1 论文解读 —— 强化学习大语言模型新时代来临?
近年来,人工智能(AI)领域发展迅猛,大语言模型(LLMs)为通用人工智能(AGI)的发展开辟了道路。OpenAI 的 o1 模型表现非凡,它引入的创新性推理时缩放技术显著提升了推理能力…...
联想拯救者R720笔记本外接显示屏方法,显示屏是2K屏27英寸
晚上23点10分前下单,第二天上午显示屏送到,检查外包装没拆封过。这个屏幕左下方有几个按键,按一按就开屏幕、按一按就关闭屏幕,按一按方便节省时间,也支持阅读等模式。 显示屏是 :AOC 27英寸 2K高清 100Hz…...
编译安装PaddleClas@openKylin(失败,安装好后报错缺scikit-learn)
编译安装 前置需求: 手工安装swig和faiss-cpu pip install swig pip install faiss-cpu 小技巧,pip编译安装的时候,可以加上--jobs64来多核编译。 注意先升级pip版本:pip install pip -U pip3 install faiss-cpu --config-s…...
传输层协议TCP与UDP:深入解析与对比
传输层协议TCP与UDP:深入解析与对比 目录 传输层协议TCP与UDP:深入解析与对比引言1. 传输层协议概述2. TCP协议详解2.1 TCP的特点2.2 TCP的三次握手与四次挥手三次握手四次挥手 2.3 TCP的流量控制与拥塞控制2.4 TCP的可靠性机制 3. UDP协议详解3.1 UDP的…...
《解码AI大模型涌现能力:从量变到质变的智能跃迁》
在当今科技飞速发展的时代,人工智能大模型的涌现能力成为了众人瞩目的焦点。从ChatGPT与用户的流畅对话,到GPT-4在复杂任务中的出色表现,这些大模型仿佛一夜之间解锁了超乎想象的技能,那么,这种神奇的涌现能力究竟是如…...
【数据结构】_C语言实现带头双向循环链表
目录 1. 单链表与双链表 1.1 单链表的结构及结点属性 1.2 双链表的结构及结点属性 2. 单链表与双链表的区别 3. 双链表的实现 3.1 List.h 3.2 List.c 3.3 Test_List.c 注:部分方法的实现细节注释 1. 双链表结点前驱、后继指针域的初始化 2. 各种增、删结…...
优盘恢复原始容量工具
买到一个优盘,显示32mb,我见过扩容盘,但是这次见到的是缩容盘,把2g的容量缩成32MB了,首次见到。。用芯片查询工具显示如下 ChipsBank(芯邦) CBM2199E 使用以下工具,恢复原始容量。。 其他CMB工具可能不行…...
JVM的GC详解
获取GC日志方式大抵有两种 第一种就是设定JVM参数在程序启动时查看,具体的命令参数为: -XX:PrintGCDetails # 打印GC日志 -XX:PrintGCTimeStamps # 打印每一次触发GC时发生的时间第二种则是在服务器上监控:使用jstat查看,如下所示,命令格式为jstat -gc…...
反转单向链表以及单链表添加节点、遍历单链表
反转1个单向链表 /*** 节点类*/ class ListNode {public int val;public ListNode next;public ListNode(int val) {this.val val;}Overridepublic String toString() {return "ListNode{" "val" val ", next" next };} }借助一个pre来存储每…...
ZZNUOJ(C/C++)基础练习1021——1030(详解版)
目录 1021 : 三数求大值 C语言版 C版 代码逻辑解释 1022 : 三整数排序 C语言版 C版 代码逻辑解释 补充 (C语言版,三目运算)C类似 代码逻辑解释 1023 : 大小写转换 C语言版 C版 1024 : 计算字母序号 C语言版 C版 代码逻辑总结…...
Linux学习笔记——系统维护命令
一、进程管理 1、ps命令(查) 来自process缩写,显示当前的进程状态。包括:进程的号码,发起者,系统资源,使用占比,运行状态等等。 语法格式:ps 参数 实例&#x…...
Harbor 部署
harbor镜像仓库搭建 版本v2.10.3 文章目录 一. docker 安装 harbor1. harbor 配置http访问1.1 下载harbor二进制包1.2 修改配置文件1.3 运行1.4 访问 2.【可选】harbor 配置https访问2.1 自签证书2.1 修改配置文件2.3 修改hosts文件2.4 运行2.5 访问 二. k8s 安装harbor1 .安装…...
three.js+WebGL踩坑经验合集(6.1):负缩放,负定矩阵和行列式的关系(2D版本)
春节忙完一轮,总算可以继续来写博客了。希望在春节假期结束之前能多更新几篇。 这一篇会偏理论多一点。笔者本没打算在这一系列里面重点讲理论,所以像相机矩阵推导这种网上已经很多优质文章的内容,笔者就一笔带过。 然而关于负缩放…...
开源的瓷砖式图像板系统Pinry
简介 什么是 Pinry ? Pinry 是一个开源的瓷砖式图像板系统,旨在帮助用户轻松保存、标记和分享图像、视频和网页。它提供了一种便于快速浏览的格式,适合喜欢整理和分享多种媒体内容的人。 主要特点 图像抓取和在线预览:支持从网页…...
LabVIEW透镜多参数自动检测系统
在现代制造业中,提升产品质量检测的自动化水平是提高生产效率和准确性的关键。本文介绍了一个基于LabVIEW的透镜多参数自动检测系统,该系统能够在单一工位上完成透镜的多项质量参数检测,并实现透镜的自动搬运与分选,极大地提升了检…...
socket实现HTTP请求,参考HttpURLConnection源码解析
背景 有台服务器,网卡绑定有2个ip地址,分别为: A:192.168.111.201 B:192.168.111.202 在这台服务器请求目标地址 C:192.168.111.203 时必须使用B作为源地址才能访问目标地址C,在这台服务器默认…...
反向代理模块jmh
1 概念 1.1 反向代理概念 反向代理是指以代理服务器来接收客户端的请求,然后将请求转发给内部网络上的服务器,将从服务器上得到的结果返回给客户端,此时代理服务器对外表现为一个反向代理服务器。 对于客户端来说,反向代理就相当…...
安卓(android)实现注册界面【Android移动开发基础案例教程(第2版)黑马程序员】
一、实验目的(如果代码有错漏,可查看源码) 1.掌握LinearLayout、RelativeLayout、FrameLayout等布局的综合使用。 2.掌握ImageView、TextView、EditText、CheckBox、Button、RadioGroup、RadioButton、ListView、RecyclerView等控件在项目中的…...
RubyFPV开源代码之系统简介
RubyFPV开源代码之系统简介 1. 源由2. 工程架构3. 特性介绍(软件)3.1 特性亮点3.2 数字优势3.3 使用功能 4. DEMO推荐(硬件)4.1 天空端4.2 地面端4.3 按键硬件Raspberry PiRadxa 3W/E/C 5. 软件设计6. 参考资料 1. 源由 RubyFPV以…...
解锁维特比算法:探寻复杂系统的最优解密码
引言 在复杂的技术世界中,维特比算法以其独特的魅力和广泛的应用,成为通信、自然语言处理、生物信息学等领域的关键技术。今天,让我们一同深入探索维特比算法的奥秘。 一、维特比算法的诞生背景 维特比算法由安德鲁・维特比在 1967 年提出…...
Unity游戏(Assault空对地打击)开发(2) 基础场景布置
目录 导入插件 文件夹整理 场景布置 山地场景 导入插件 打开【My Assets】(如果你刚进行上篇的操作,该窗口默认已经打开了)。 找到添加的几个插件,点击Download并Import x.x to...。 文件夹整理 我们的目录下多了两个文件夹&a…...
Office / WPS 公式、Mathtype 公式输入花体字、空心字
注:引文主要看注意事项。 1、Office / WPS 公式中字体转换 花体字 字体选择 “Eulid Math One” 空心字 字体选择 “Eulid Math Two” 使用空心字时,一般不用斜体,取消勾选 “斜体”。 2、Mathtype 公式输入花体字、空心字 2.1 直接输…...
代码随想录算法训练营第三十九天-动态规划-213. 打家劫舍 II
与上一题基本一样,只不过房间形成一个环,就需要在首尾考虑状况多一些这不是多一些状况的问题,是完全不知道如何选择的问题这种状况详细分析一下就是要分成三种情况 第一种:不考虑首元素,也不考虑尾元素,只考…...
自然语言处理-词嵌入 (Word Embeddings)
词嵌入(Word Embedding)是一种将单词或短语映射到高维向量空间的技术,使其能够以数学方式表示单词之间的关系。词嵌入能够捕捉语义信息,使得相似的词在向量空间中具有相近的表示。 📌 常见词嵌入方法 基于矩阵分解的方…...
Redis 数据备份与恢复
Redis 数据备份与恢复 引言 Redis 是一款高性能的键值对存储系统,广泛应用于缓存、消息队列、分布式锁等领域。为了保证数据的安全性和可靠性,定期对 Redis 数据进行备份与恢复是至关重要的。本文将详细介绍 Redis 数据备份与恢复的方法,帮助您更好地管理和维护 Redis 数据…...
【leetcode】T541 (两点反思)
解题反思 闷着头往,往往会写成一团浆糊,还推倒重来,谋划好全局思路再开始很重要。 熟悉C的工具库很重要,一开始看到反转就还想着用stack来着,后面突然想起来用reverse函数刚好可以用哇,这题也就迎刃而解了…...
《STL基础之vector、list、deque》
【vector、list、deque导读】vector、list、deque这三种序列式的容器,算是比较的基础容器,也是大家在日常开发中常用到的容器,因为底层用到的数据结构比较简单,笔者就将他们三者放到一起做下对比分析,介绍下基本用法&a…...