【二叉树】(二)二叉树的基础修改构造及属性求解1

(二)二叉树的基础修改构造及属性求解1

  • 翻转二叉树
    • 递归实现
    • 迭代实现(深度遍历)
    • 层序实现(广度遍历)
  • 对称二叉树
    • 递归实现
    • 迭代实现(非层序遍历)
  • 二叉树的最大深度
    • 递归法
    • 迭代法(层序遍历)
  • 二叉树的最小深度
    • 解题思路
    • 递归法
    • 迭代法(层序遍历)
  • 完全二叉树的节点个数
    • 普通二叉树
    • 完全二叉树
  • 平衡二叉树

翻转二叉树

力扣原题链接:226. 翻转二叉树
给定一棵二叉树的根节点 root ,翻转这棵二叉树,并返回其根节点。

这道题目是非常经典的题目,也是比较简单的题目

思路:

  • 注意只要把每一个节点的左右孩子翻转一下,就可以达到整体翻转的效果**
  • 这道题目使用前序遍历和后序遍历都可以,唯独中序遍历不方便,因为中序遍历会把某些节点的左右孩子翻转了两次! 拿纸画一画,就理解了

递归实现

1. 确定递归函数的参数和返回值
  参数就是要传入节点的指针,不需要其他参数了,通常此时定下来主要参数,如果在写递归的逻辑中发现还需要其他参数的时候,随时补充。
  返回值的话其实也不需要,但是题目中给出的要返回root节点的指针,可以直接使用题目定义好的函数,所以就函数的返回类型为TreeNode*

TreeNode* invertTree(TreeNode* root)

2. 确定终止条件
当节点为空的时候,就返回

if (root == NULL) return root;

3. 确定单层递归的逻辑
因为是先前序遍历,所以先进行交换左右孩子节点,然后反转左子树,反转右子树。

swap(root->left, root->right);	//中
invertTree(root->left);			//左
invertTree(root->right);		//右

完整代码:

TreeNode* invertTree(TreeNode* root)
{
     if (root == NULL) 
     	return root;
     swap(root->left, root->right);  // 中
     invertTree(root->left);         // 左
     invertTree(root->right);        // 右
     return root;
}

后续遍历: 后续遍历顺序是左右中,因此只需要将交换放到最后一个处理即可。

TreeNode* invertTree(TreeNode* root) 
{
	if (root == NULL) 
		return root;
	invertTree(root->left);         // 左
	invertTree(root->right);        // 右
	swap(root->left, root->right);  // 中
	return root;
}

拓展: 中序遍历
  对于中序遍历是否简单的交换程序即可呢?答案是否定的。使用递归的中序遍历,某些节点的左右孩子会翻转两次。
如果非要使用递归中序的方式写,也可以,如下代码就可以避免节点左右孩子翻转两次的情况:

TreeNode* invertTree(TreeNode* root) 
{
	if (root == NULL) 
		return root;
	invertTree(root->left);         // 左
	swap(root->left, root->right);  // 中
	//注意 这里依然要遍历左孩子,因为中间节点已经翻转了
	invertTree(root->left);      	//右  
	return root;
}

迭代实现(深度遍历)

//迭代法翻转二叉树
TreeNode* invert2Tree(TreeNode* root) 
{
	if(root == NULL)
		return root;
	stack<TreeNode*> st;
	st.push(root);
	while(!st.empty())
	{
		TreeNode* node = st.top();
		st.pop();
		swap(node->left, node->right);	//中
		if(node->left)				
			st.push(node->left);		//左
		if(node->right)
			st.push(node->right);		//右	
	}
}

如果这个代码不太熟悉的话可以再回顾一下二叉树的迭代遍历。

层序实现(广度遍历)

//层序法翻转二叉树
TreeNode* invert3Tree(TreeNode* root) 
{
	queue<TreeNode*> que;
	int size;
	if(root != NULL)
		que.push(root);
	while(!que.empty())
	{
		size = que.size();
		while(size--)
		{
			TreeNode* node = que.front();
			que.pop();
			swap(node->left, node->right);	//中
			if(node->left)
 				que.push(node->left);		//左
 			if(node->right)
 				que.push(node->right);		//右
		}
	}
	return root;
}

如果对以上代码不理解,或者不清楚二叉树的层序遍历,可以回顾一下二叉树的层序遍历。


对称二叉树

力扣原题链接:101. 对称二叉树
给定一个二叉树,检查它是否是镜像对称的

  对于二叉树是否对称,要比较的是根节点的左子树与右子树是不是相互翻转的,理解这一点就知道了其实我们要比较的是两个树(这两个树是根节点的左右子树),所以在递归遍历的过程中,也是要同时遍历两棵树。

确定遍历顺序:
比较的是两个子树的里侧和外侧的元素是否相等。如图所示:

  • 本题遍历只能是“后序遍历”,因为我们要通过递归函数的返回值来判断两个子树的内侧节点和外侧节点是否相等。

  • 正是因为要遍历两棵树而且要比较内侧和外侧节点,所以准确的来说是一个树的遍历顺序是左右中,一个树的遍历顺序是右左中。

递归实现

递归三部曲

1. 确定递归函数的参数和返回值
  因为我们要比较的是根节点的两个子树是否是相互翻转的,进而判断这个树是不是对称树,所以要比较的是两个树,参数自然也是左子树节点和右子树节点。返回值自然是bool类型。

bool compare(TreeNode* left, TreeNode* right)

2. 确定终止条件
  要比较两个节点数值相不相同,首先要把两个节点为空的情况弄清楚! 否则后面比较数值的时候就会操作空指针了。

  • 左节点为空,右节点不为空,不对称,return false
  • 左不为空,右为空,不对称 return false
  • 左右都为空,对称,return true
  • 左右都不为空,且数值不相等,不对称,return false

代码如下:

if(left == NULL && right != NULL)		return false;
else if (left != NULL && right == NULL) return false;	
else if(left == NULL && right == NULL)	return true;
//都不为空
else
{
	//不对称
	if(left->val != right ->val)	return false;
	//对称 处理递归单层逻辑
	else
	{
	
	}
}

3. 确定单层递归的逻辑
  此时才进入单层递归的逻辑,单层递归的逻辑就是处理 左右节点都不为空,且数值相同的情况。

  • 比较二叉树外侧是否对称:传入的是左节点的左子树,右节点的右子树。
  • 比较内侧是否对称,传入左节点的右子树,右节点的左子树。
  • 如果左右都对称就返回 true ,有一侧不对称就返回 false

代码如下:

//判断左右节点是否对称
bool outSide = compare(left->left,  right->right);	//左子树:	左	//左子树: 右
bool inSide  = compare(left->right, right->left);	//左子树:	右	//左子树: 左	
//返回结果到父节点				
if(outSide == true && inSide == true)	//左子树:	中	//右子树: 中
	return true;
else
	return false;	
//左子树:	左右中		右子树: 右左中  都是后续遍历

如上代码中,我们可以看出使用的遍历方式,左子树左右中,右子树右左中,所以我把这个遍历顺序也称之为“后序遍历”(尽管不是严格的后序遍历)。

最后递归的C++整体代码如下:

bool compare(TreeNode *left, TreeNode *right)
{
	//左右一边为空
	if(left == NULL && right != NULL)
		return false;
	else if (left != NULL && right == NULL) 
		return false;
	//都为空
	else if(left == NULL && right == NULL)
		return true;
	//都不为空
	else
	{
		//不对称
		if(left->val != right ->val)
			return false;
		//对称 处理递归单层逻辑
		else
		{
			//判断左右节点是否对称
			bool outSide = compare(left->left,  right->right);	//左子树:	左	//左子树: 右
			bool inSide  = compare(left->right, right->left);	//左子树:	右	//左子树: 左	
			//返回结果到父节点
			if(outSide == true && inSide == true)	//左子树:	中	//左子树: 中
				return true;
			else
				return false;	
			//左子树:	左右中		右子树: 右左中  都是后续遍历
		}
	}
}
//掉用递归函数
bool isSymmetric(TreeNode* root) 
{
	if(root == NULL)
		return true;
	bool ret = compare(root->left, root->right);
	return ret;
}
	

迭代实现(非层序遍历)

  这道题目我们也可以使用迭代法,但要注意,这里的迭代法可不是前中后序的迭代写法,因为本题的本质是判断两个树是否是相互翻转的,其实已经不是所谓二叉树遍历的前中后序的关系了。这里我们可以使用队列来比较两个树(根节点的左右子树)是否相互翻转,(注意这不是层序遍历)

使用队列
通过队列来判断根节点的左子树和右子树的内侧和外侧是否相等,如动画所示:

代码如下:

//迭代实现 使用队列
bool isSymmetric(TreeNode* root) 
{
	if(root == NULL)
		return true;
	queue<TreeNode*> que;
	//左右子树入队列
	que.push(root->left);
	que.push(root->right);
	
	while(!que.empty())
	{
		TreeNode* leftNode  = que.front();	que.pop();	//左子树根节点
		TreeNode* rightNode = que.front();	que.pop();	//右子树根节点
		if(leftNode == NULL && rightNode == NULL)		//左右子树都为空 对称
			continue;
		else if(leftNode == NULL && rightNode != NULL)
			return false;
		else if(leftNode != NULL && rightNode == NULL)
			return false;
		
		//保证节点不为空
		if(leftNode -> val == rightNode -> val)	//数值相等 继续判断子树
		{
			que.push(leftNode->left);
			que.push(rightNode->right);
			que.push(leftNode->right);
			que.push(rightNode->left);
		}
		else		//都不为空 但数值不等 不对称
			return false;
	}
	return	true;
}	

二叉树的最大深度

力扣原题链接:104. 二叉树的最大深度
给定一个二叉树 root ,返回其最大深度。
  

返回它的最大深度 3

  • 二叉树节点的深度:指从根节点到该节点的最长简单路径边的条数或者节点数
  • 二叉树节点的高度:指从该节点到叶子节点的最长简单路径边的条数或者节点数

而根节点的高度就是二叉树的最大深度,所以本题中我们通过后序求的根节点高度来求的二叉树最大深度。

递归法

确定递归函数的参数和返回值: 参数就是传入树的根节点,返回就返回这棵树的深度,所以返回值为int类型。

int getHeight(TreeNode* node)

确定终止条件: 如果为空节点的话,就返回0,表示高度为0

if(node == NULL)
	return 0;

确定单层递归的逻辑: 先求它的左子树的深度,再求右子树的深度,最后取左右深度最大的数值 再+1 (加1是因为算上当前中间节点)就是目前节点为根节点的树的深度

int leftDepth  = getHeight(node->left);		//左
int rightDepth = getHeight(node->right);	//右
return 1 + max(leftDepth,rightDepth);		//中

所以整体c++代码如下:

	//递归法 递归函数
	int getHeight(TreeNode* node)
	{
		if(node == NULL)
			return 0;
		int leftDepth  = getHeight(node->left);		//左
		int rightDepth = getHeight(node->right);	//右
		return 1 + max(leftDepth,rightDepth);		//中
	}	
	int maxDepth(TreeNode* root) {
		return getHeight(root);
    }

迭代法(层序遍历)

  当然这题也可以使用迭代法,使用层序遍历是最为合适的,因为最大的深度就是二叉树的层数,和层序遍历的方式极其吻合。在二叉树中,一层一层的来遍历二叉树,记录一下遍历的层数就是二叉树的深度,如图所示:

所以这道题的迭代法就是一道模板题,可以使用二叉树层序遍历的模板来解决,只需记录二叉树的层数即可,代码如下:

//使用层序遍历
 int maxDepth(TreeNode* root)
 {
 	//入口参数检查
 	if(root == NULL)
 		return 0;
 	int depth = 0;				//树深度
 	int size = 0;				//没一层节点个数
 	queue<TreeNode*> que;	//存放节点队列
 	que.push(root);
 	
 	while(!que.empty())
 	{
 		size = que.size();	 //记录当前层节点数量
while(size--)
{	
	TreeNode* node = que.front();
 			que.pop();
  			
  		if(node->left)
		que.push(node->left);
	if(node->right)
		que.push(node->right);
}
size = que.size();	 //更新队列大小
depth++;	
}
return depth;
}

若对该程序不熟悉或对层次遍历不熟悉的话请,回顾复习二叉树的层序遍历方式。


二叉树的最小深度

力扣原题链接:111. 二叉树的最小深度

给定一个二叉树,找出其最小深度。

最小深度是从根节点到最近叶子节点的最短路径上的节点数量。

说明: 叶子节点是指没有左右子节点的节点。

解题思路

直觉上好像和求最大深度差不多,其实还是差不少的。本题依然可以使用上述的后序求二叉树的高度。

但本题还有一个误区,在处理节点的过程中,最大深度很容易理解,最小深度就不那么好理解,如图:

若完整照搬修改求最大深度的程序,则求得上述概述的最小深度是1,因为在求min时,左侧的子树为空,返回0,因此需要考虑左右子树为空的情况。

递归法

确定递归函数的参数和返回值 参数为要传入的二叉树根节点,返回的是int类型的深度,代码如下:

int getMinHeight(TreeNode* node)

确定终止条件 终止条件也是遇到空节点返回0,表示当前节点的高度为0,代码如下:

if(node == NULL)
	return 0;

确定单层递归的逻辑
这块和求最大深度可就不一样了,可能会模仿求最大深度写成如下代码:

int leftDepth  = getMinHeight(node->left);	//左
int rightDepth = getMinHeight(node->right);	//右
return 1 + min(leftDepth, rightDepth);		//中

这个代码就犯了此图中的误区:

如果这么求的话,没有左孩子的分支会算为最短深度。

所以,如果左子树为空,右子树不为空,说明最小深度是 1 + 右子树的深度。

反之,右子树为空,左子树不为空,最小深度是 1 + 左子树的深度。 最后如果左右子树都不为空,返回左右子树深度最小值 + 1 。

代码如下:

int leftDepth  = getMinHeight(node->left);		//左
int rightDepth = getMinHeight(node->right);		//右

//中
//左子树为空 返回右侧深度
if(node->left == NULL && node->right != NULL)
	return rightDepth + 1;
//右子树为空 返回左侧深度
else if(node->left != NULL && node->right == NULL)
	return leftDepth + 1;
//返回左右子树最深度
else
	return 1 + min(leftDepth, rightDepth);	

遍历的顺序为后序(左右中),可以看出:求二叉树的最小深度和求二叉树的最大深度的差别主要在于处理左右孩子不为空的逻辑。

整体递归代码如下:

int getMinHeight(TreeNode* node)
{
	if(node == NULL)
		return 0;
	int leftDepth  = getMinHeight(node->left);		//左
	int rightDepth = getMinHeight(node->right);		//右
	
	//中
	//左子树为空 返回右侧深度
	if(node->left == NULL && node->right != NULL)
		return rightDepth + 1;
	//右子树为空 返回左侧深度
	else if(node->left != NULL && node->right == NULL)
		return leftDepth + 1;
	//返回左右子树最深度
	else
		return 1 + min(leftDepth, rightDepth);	
}
int minDepth(TreeNode* root) {
	return getMinHeight(root);
} 

迭代法(层序遍历)

当然本题还可以使用层序遍历的方式来解决,思路是一样的,如果对于层序遍历或者下列程序不清楚的话,可以回顾二叉树的层序遍历思想和程序设计。层序遍历示意图:

需要注意的是,只有当左右孩子都为空的时候,才说明遍历到最低点了。 如果其中一个孩子不为空则不是最低点
代码如下:

//迭代法 层序遍历
int minDepth(TreeNode* root) 
{
	if(root == NULL)
		return 0;
	int depth = 0;
	int size = 0;
	queue<TreeNode*> que;
	que.push(root);
	while(!que.empty())
	{
		size = que.size();	//获取队列大小
		depth++;
		while(size--)
		{
			TreeNode* node = que.front();
			que.pop();
			if(node == NULL)
				continue;
			if(node->left)
				que.push(node->left);
			if(node->right)
				que.push(node->right);
			if(node->left == NULL && node->right == NULL)
				return depth;
		}
	}
	return depth;
}

完全二叉树的节点个数

力扣原题链接:222. 完全二叉树的节点个数

给出一棵 完全二叉树 的根节点 root ,求出该树的节点个数。

普通二叉树

  首先按照普通二叉树的逻辑来求。这道题目的递归法和求二叉树的深度写法类似而迭代法,记录遍历的节点数量就可以了,对于递归就是计算节点的左右子树的节点数量。迭代层序遍历的代码不再赘述,相信通过迭代法做完以上题目后已易如反掌的求解二叉树的节点数量。

递归遍历的顺序依然是后序(左右中),其中递归的完整代入如下所示:

//获取普通二叉树节点数量 递归算法
int getNum(TreeNode* node)
{
	if(node == NULL)
		return 0;
	//后续遍历
	int leftNum  = getNum(node->left);	//左
	int rightNum = getNum(node->right);	//右
	return leftNum + rightNum + 1;		//中
} 

完全二叉树

完全二叉树只有两种情况,情况一:就是满二叉树,情况二:最后一层叶子节点没有满。

对于情况一,可以直接用 2^树深度 - 1 来计算,注意这里根节点深度为1。

对于情况二,分别递归左孩子,和右孩子,递归到某一深度一定会有左孩子或者右孩子为满二叉树,然后依然可以按照情况1来计算。
完全二叉树情况(一)(二)如图:

因此计算完全二叉树的递归算法即判断左右子树是否为满二叉树,并返回当前节点为根节点的节点个数。

可以看出如果整个树不是满二叉树,就递归其左右孩子,直到遇到满二叉树为止,用公式计算这个子树(满二叉树)的节点数量。

如何判断是否为满二叉树: 在完全二叉树中,如果递归向左遍历的深度等于递归向右遍历的深度,那说明就是满二叉树,如果深度不等,则说明不是满二叉树,如图所示:

判断其子树是不是满二叉树,如果是则利用公式计算这个子树(满二叉树)的节点数量,如果不是则继续递归,那么 在递归三部曲中,第二部:终止条件的写法应该是这样的

//空节点
if(node == NULL)
	return 0;
	
//满二叉树 结束
int leftDepth  = 0;
int rightDepth = 0;
TreeNode* leftNode  = node->left;
TreeNode* rightNode = node->right;	
//向左遍历
while(leftNode)
{
	leftNode = leftNode->left;
	leftDepth++;
}
//向右遍历
while(rightNode)
{
	rightNode = rightNode->right;
	rightDepth++;
}
//左右深度相等 满二叉树
if(leftDepth == rightDepth)	
	return (2<<leftDepth) - 1;

单层递归的逻辑:

//单层递归逻辑
int leftNum  = getNum(node->left);	//左
int rightNum = getNum(node->right);	//右
return leftNum + rightNum + 1;		//中

最后完整的递归程序实现代码如下:

//获取完全二叉树节点数量 
//递归算法:判断子树是否为满二叉树
//满二叉树的判断:向左遍历和向右遍历的深度是一致的
//(前提:已经是一棵完全二叉树)
int getNum(TreeNode* node)
{
	if(node == NULL)
		return 0;
	
	//满二叉树 结束
	int leftDepth  = 0;
	int rightDepth = 0;
	TreeNode* leftNode  = node->left;
	TreeNode* rightNode = node->right;	
	//向左遍历
	while(leftNode)
	{
		leftNode = leftNode->left;
		leftDepth++;
	}
	//向右遍历
	while(rightNode)
	{
		rightNode = rightNode->right;
		rightDepth++;
	}
	//满二叉树
	if(leftDepth == rightDepth)	
		return (2<<leftDepth) - 1;
		
	//单层递归逻辑
	int leftNum  = getNum(node->left);	//左
	int rightNum = getNum(node->right);	//右
	return leftNum + rightNum + 1;		//中
}
int countNodes(TreeNode* root) 
{
	return getNum(root);
}

平衡二叉树

力扣原题链接:110. 平衡二叉树

给定一个二叉树,判断它是否是 平衡二叉树

本题中,一棵高度平衡二叉树定义为:一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过1。

示例 1:

  • 二叉树节点的深度:指从根节点到该节点的最长简单路径边的条数。
  • 二叉树节点的高度:指从该节点到叶子节点的最长简单路径边的条数,但leetcode中强调的深度和高度很明显是按照节点来计算的,如图:


因为求深度可以从上到下去查 所以需要前序遍历(中左右),而高度只能从下到上去查,所以只能后序遍历(左右中)

1. 明确递归函数的参数和返回值
参数:当前传入节点。 返回值:以当前传入节点为根节点的树的高度。

// -1 表示已经不是平衡二叉树了,否则返回值是以该节点为根节点树的高度
int getHeight(TreeNode* node)

2. 明确终止条件
递归的过程中依然是遇到空节点了为终止,返回0,表示当前节点为根节点的树高度为0,代码如下:

if (node == NULL) {
    return 0;
}

3. 明确单层递归的逻辑
通过左子树高度和其右子树高度的差值判断是否为平衡二叉树,如果差值小于等于1,则返回当前二叉树的高度,否则返回-1,表示已经不是二叉平衡树了。

//计算左子树的高度 并判断是否为平衡二叉树
int leftHeight  = getHeight(node->left);
if(leftHeight == -1)	return -1;
//计算右子树的高度 并判断是否为平衡二叉树
int rightHeight = getHeight(node->right);
if(rightHeight == -1)	return -1;

//左右子树是平衡二叉树 但高度差大于1
if(abs(leftHeight - rightHeight) > 1)
	return -1;
else
	return 1 + max(leftHeight,rightHeight);

最后本题整体递归代码如下:

class Solution {
public:
	int getHeight(TreeNode* node)
	{
		if(node == NULL)
			return 0;
			
		//计算左子树的高度 并判断是否为平衡二叉树
		int leftHeight  = getHeight(node->left);
		if(leftHeight == -1)	return -1;
		//计算右子树的高度 并判断是否为平衡二叉树
		int rightHeight = getHeight(node->right);
		if(rightHeight == -1)	return -1;
		
		//左右子树是平衡二叉树 但高度差大于1
		if(abs(leftHeight - rightHeight) > 1)
			return -1;
		else
			return 1 + max(leftHeight,rightHeight);
	}
	
	bool isBalanced(TreeNode* root) {
		int ret  = getHeight(root);
		if(ret != -1)
			return true;
		else
			return false;
    }	
};

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

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

相关文章

你了解黑龙江等保测评么?

等保测评的全称是信息安全等级保护测评&#xff0c;是信息安全等级保护工作中的一项重要内容。 具体来说&#xff0c;等保测评是指按照国家相关标准和技术规范&#xff0c;对信息系统安全等级保护状况进行检测评估的活动。 其主要目的是发现信息系统存在的安全隐患和不足&…

学会给文件夹加密,保密措施不可或缺!

我们的个人信息、工作文件和其他重要数据都存储在各种设备和文件夹中&#xff0c;如何保证这些数据的安全&#xff0c;防止未经授权的访问和泄露&#xff0c;成为了一个不容忽视的问题。本文将探讨给文件夹加密的必要性&#xff0c;以及如何在手机和电脑上进行文件夹加密。 操作…

使用KNN预测一个新的点,以及将这个点用五角星进行matplotlib可视化展示

概述 基于之前的KNN案例继续做一些操作。 之前的完整代码如下&#xff1a; from sklearn.datasets import make_blobs # KNN 分类器 from sklearn.neighbors import KNeighborsClassifier # 画图工具 import matplotlib.pyplot as plt # 数据集拆分工具 from sklearn.model_…

DiskGenius帮你恢复系统无法识别的U盘数据

场景还原 前两天早上U盘复制文件卡死后&#xff0c;强行断开U盘&#xff0c;再次使用直接无法访问&#xff0c;心拔凉拔凉&#xff01;&#xff01; 使用驱动器G:中的光盘之前需要将其格式化 位置不可用-无法访问U盘 常规科普 一、U盘无法识别 1、检查U盘是否插入正确&…

【汇编语言】多文件组织

【汇编语言】多文件组织 文章目录 【汇编语言】多文件组织前言一、8086拓展1.子程序的另外一种写法2.程序的多文件组织 总结 前言 本篇文章将讲到子程序的另一种写法&#xff0c;以及程序的多文件组织。 一、8086拓展 1.子程序的另外一种写法 初始的程序 在这里我们对比一下…

6款电脑精选工具软件推荐!

AI视频生成&#xff1a;小说文案智能分镜智能识别角色和场景批量Ai绘图自动配音添加音乐一键合成视频https://aitools.jurilu.com/ 1.IP地址查看工具——纯真ip数据库 纯真IP数据库是一个易于操作的IP地址查询工具&#xff0c;它允许用户通过输入IP地址来查询其对应的地理位置…

每天五分钟玩转深度学习pytorch:pytorch中的张量类型

本文重点 和numpy一样,pytorch中也有自己的类型,本节课程我们将对它的类型进行介绍,并且学习不同的类型之间的转换,这是pytorch的基础。 基本类型 pytorch的基本变量称为张量Tensor,这张表是pytorch中的类型,Tensor有不同的类型,他和很多编程语言中的类型相似,它有 32…

ROS学习笔记(15)小车巡墙驾驶

0.前提 前一章我讲解了拉氏变换和PID&#xff0c;这一章我来讲解一下小车巡墙驾驶的理论和部分代码。 1.前情回顾 1.拉氏变换 拉普拉斯变换是要将时域问题转换成频域问题来处理。 2.PID控制器 转向角&#xff1a; 误差牺牲&#xff1a; 3.具体参看上一篇文章 2.巡墙驾驶…

AI 一键生成高清短视频,视频 UP 主们卷起来...

现在短视频越来越火&#xff0c;据统计&#xff0c;2023年全球短视频用户数量已达 10 亿&#xff0c;预计到2027年将突破 24 亿。对于产品展示和用户营销来说&#xff0c;短视频已经成为重要阵地&#xff0c;不管你喜不喜欢它&#xff0c;你都得面对它&#xff0c;学会使用它。…

Proxy和Reflect,打造灵活的JS代理机制 (代码示例)

在 JavaScript 中&#xff0c;代理&#xff08;Proxy&#xff09;和反射&#xff08;Reflect&#xff09;是 ES6 引入的两个新特性。Proxy用于创建一个对象的代理&#xff0c;从而实现对这个对象的操作的拦截、转换或扩展&#xff1b;而Reflect则提供了一系列与 JavaScript 运行…

线上3D博物馆搭建简单吗?有何优势?有哪些应用场景?

随着科技的飞速发展&#xff0c;传统的博物馆参观方式正在经历一场前所未有的变革&#xff0c;在科技的“加持”下&#xff0c;不少博物馆凭借强大的技术、创意和美学实践&#xff0c;频频“出圈”&#xff0c;线上3D博物馆逐渐崛起&#xff0c;这不仅丰富了人们的文化体验&…

Java集合之HashMap

概述 HashMap是基于哈希表的Map接口实现的一种存储key、value的数据结构&#xff0c;提供了所有可选的映射操作&#xff0c;且键值允许null的存在&#xff0c;不保证数据映射的顺序&#xff0c;也不能保证顺序在一段时间内保持不变 底层结构 jdk1.7&#xff1a;数组链表 jdk…

污水处理环保设备厂商怎么选

在选择污水处理环保设备厂商时&#xff0c;需要综合考虑多个因素来确保选取的供应商能够提供高质量的设备和服务。以下是一些主要的考虑因素&#xff1a; 企业资质和认证&#xff1a;首先检查供应商是否拥有相关的资质证书和行业认证&#xff0c;例如ISO 9001质量管理体系认证、…

[Linux]一篇文章带你全面理解信号

文章目录 初识信号一、什么是信号二、为什么要有信号 看见信号一、先见一下Linux中的信号&#xff1a;二、如何产生信号三、自定义信号的处理行为&#xff08;自定义捕捉&#xff09; 了解信号一、信号的保存二、block、pending表使用代码查看三、一些倔强的&#xff0c;无法被…

亚马逊自养号测评策略:提升店铺产品权重的秘诀

对于卖家而言&#xff0c;拥有一款爆款产品无疑是获得流量的关键&#xff0c;同时它也能显著提升店铺的销量。因此&#xff0c;大部分卖家都热衷于学习如何打造爆款产品的策略&#xff0c;特别是对于那些致力于经营自己店铺的卖家来说&#xff0c;掌握这一技巧对于店铺的成功运…

JWT令牌技术实现登录校验

一.简单登录功能 在登录界面中&#xff0c;我们可以输入用户的用户名以及密码&#xff0c;然后点击 "登录" 按钮就要请求服务器&#xff0c;服务端判断用户输入的用户名或者密码是否正确。如果正确&#xff0c;则返回成功结果&#xff0c;跳转至系统首页面。 1.功能…

前端JS必用工具【js-tool-big-box】学习,生成uuid,数组去重

js-tool-big-box这个前端工具库&#xff0c;今天又添加了2个实用功能&#xff0c;分别是生成uuid和数组去重。 目录 1 安装并引入 2 生成uuid 3 数组去重 1 安装并引入 安装最新版的js-tool-big-box工具包 由于生成uuid和数组去重属于两个不同对象下的方法&#xff0c;所以…

照片尺寸怎么修改?这几个图片处理方式都可以

修改图片尺寸在许多场景中都是常见的需求&#xff0c;包括网页设计、图片编辑、手机应用程序开发、幻灯片演示、社交媒体和博客、以及打印和出版物设计&#xff0c;通过调整图片大小&#xff0c;可以适应不同的布局和设备要求&#xff0c;那么问题来了&#xff0c;如何将图片改…

国外客户怀疑我们产品质量要如何应对

经常有外贸小伙伴问我&#xff0c;国外客户怀疑我们的产品质量要如何应对&#xff1f; 这个问题应该算是外贸经常遇到的一个问题&#xff0c;今天就简单来给大家分享几个我认为可以去入手跟客户回复解决的这个问题的点。 首先&#xff0c;我们要知道&#xff0c;不管你做啥产品…