012 C++ AVL_tree

前言

本文将会向你介绍AVL平衡二叉搜索树的实现

引入AVL树

二叉搜索树虽可以缩短查找的效率,但如果数据有序或接近有序普通的二叉搜索树将退化为单支树,查找元素相当于在顺序表中搜索元素,效率低下。因此,两位俄罗斯的数学家G.M.Adelson-Velskii和E.M.Landis在1962年发明了一种解决上述问题的方法(AVL树是以这两位的名字命名的):当向二叉搜索树中插入新结点后,如果能保证每个结点的左右子树高度之差的绝对值不超过1,超过了1需要对树中的结点进行调整(旋转),即可降低树的高度,从而减少平均搜索长度。

平衡因子

AVL树的平衡因子是指一个节点的左子树的高度减去右子树的高度的值。在AVL树中,每个节点的平衡因子必须为-1、0或1,如果不满足这个条件,就需要通过旋转操作来重新平衡树。AVL树的平衡因子可以帮助我们判断树的平衡状态,并且在插入进行相应的调整,以保持树的平衡性。

节点的创建

除了需要增加一个_bf平衡因子,这里还多加了一个pParent的结构体指针便于我们向上遍历对平衡因子进行调整

struct AVLTreeNode
{
	AVLTreeNode(const T& data = T())
		: _pLeft(nullptr)
		, _pRight(nullptr)
		, _pParent(nullptr)
		, _data(data)
		, _bf(0)
	{}

	AVLTreeNode<T>* _pLeft;
	AVLTreeNode<T>* _pRight;
	AVLTreeNode<T>* _pParent;
	T _data;
	int _bf;   // 节点的平衡因子
};

插入节点

先按照二叉搜索树的规则将节点插入到AVL树中
新节点插入后,AVL树的平衡性可能会遭到破坏,此时就需要更新平衡因子,并检测是否破坏了AVL树的平衡性
cur插入后,pParent的平衡因子一定需要调整,在插入之前,pParent的平衡因子分为三种情况:-1,0, 1, 分以下两种情况:

如果cur插入到pParent的左侧,只需给pParent的平衡因子-1即可
如果cur插入到pParent的右侧,只需给pParent的平衡因子+1即可

此时:pParent的平衡因子可能有三种情况:0,正负1, 正负2

1. 如果pParent的平衡因子为0,说明插入之前pParent的平衡因子为正负1,插入后被调整成0,此时满足AVL树的性质,插入成功
2. 如果pParent的平衡因子为正负1,说明插入前pParent的平衡因子一定为0,插入后被更新成正负1,此时以pParent为根的树的高度增加,需要继续向上更新
3. 如果pParent的平衡因子为正负2,则pParent的平衡因子违反平衡树的性质,需要对其进行旋转处理

	// 在AVL树中插入值为data的节点
	bool Insert(const T& data)
	{
		Node* cur = _pRoot;
		Node* parent = nullptr;
		if (_pRoot == nullptr)
		{
			//直接插入
			_pRoot = new Node(data);
			//插入成功
			return true;
		}
		//寻找插入位置
		else
		{
			Node* parent = cur;
			while (cur)
			{
				parent = cur;
				if (cur->_data > data)
				{
					cur = cur->_pLeft;
				}
				else if (cur->_data < data)
				{
					cur = cur->_pRight;
				}
				//已有
				else return false;
			}
			cur = new Node(data);
			//插入+链接
			if (parent->_data > data)
			{
				parent->_pLeft = cur;
			}
			else
			{
				parent->_pRight = cur;
			}
			//链接
			cur->_pParent = parent;
		}
		//更新平衡因子
		while (parent)
		{
			if (cur == parent->_pRight)
			{
				parent->_bf++;
			}
			else if (cur == parent->_pLeft)
			{
				parent->_bf--;
			}

			if (parent->_bf == 0)
			{
				//插入后子树稳定,不用向上更新平衡因子
				return true;
			}
			else if (parent->_bf == 1 || parent->_bf == -1)
			{
				return true;
			}
			else if (parent->_bf == 2 || parent->_bf == -2)
			{
				if (parent->_bf == 2 && cur->_bf == 1)
				{
					//左旋 (右高左低,往左边压)
					RotateL(parent);
				}
				else if (parent->_bf == -2 && cur->_bf == -1)
				{
					//右旋(左高右低,往右边压)
					RotateR(parent);
				}
				else if (parent->_bf == 2 && cur->_bf == -1)
				{
					//右左双旋(不是单独的左右有一方低,有一方高)
					RotateL(parent);
				}
				else if (parent->_bf == -2 && cur->_bf == 1)
				{
					//左右双旋(不是单独的左右有一方低,有一方高)
					RotateR(parent);
				}
				parent = parent->_pParent;
				cur = cur->_pParent; 
			}
			else
			{
				return false;
			}
			return true;
		}
	}


右单旋

左高右低,往右边旋(根据平衡因子判断(右子树的高度减去左子树的高度))
细节分析+代码
在这里插入图片描述

整体思路
在这里插入图片描述
在这里插入图片描述

	void RotateR(Node* pParent)
	{
		Node* pPnode = pParent->_pParent;
		Node* subL = pParent->_pLeft;
		Node* subLR = subL->_pRight;
		if (subLR)
		{
			pParent->_pLeft = subL->_pRight;
			subL->pParent = pParent;
		}
		subL->_pRight = pParent;
		pParent->_pParent = subL;
		//旋转部分子树
		if (pPnode)
		{
			//是左子树
			if (pPnode->_pLeft == pParent)
			{
				pPnode->_pLeft = subL;
				subL->pParent = pPnode;
			}
			//是右子树
			else
			{
				pPnode->_pLeft = subL;
				subL->pParent = pPnode;
			}
		}
		//旋转整棵子树
		else
		{
			_pRoot = subL;
			subL->pParent = nullptr;
		}
		//调节平衡因子
		pParent->_bf = subL->_bf = 0;
	}

左单旋

这里作统一说明:h表示子树的高度,绿色标记的数字为节点的平衡因子,长方形表示的是一棵抽象的子树
右高左低,往左边旋(根据平衡因子判断(右子树的高度减去左子树的高度))
左单旋和右单旋的思路很像,这里就不再进行细节分析。

整体思路
在这里插入图片描述
在这里插入图片描述

void RotateL(Node* pParent)
	{
		Node* pPnode = pParent->_pParent;
		Node* subR = pParent->_pRight;
		Node* subRL = subR->_pLeft;//可能为空
		if (subRL)
		{
			pParent->_pRight = subRL;
			subRL->_pParent = pParent;
		}
		subR->_pLeft = pParent;
		pParent->_pParent = subR;

		//链接:旋转整棵树
		if (pPnode == nullptr)
		{
			_pRoot = subR;
			subR->_pParent = nullptr;
		}
		//链接:旋转子树
		else
		{
			if (pPnode->_pLeft == pParent)
			{
				pPnode->_pLeft = subR;
				subR->_pParent = pPnode;
			}
			else if (pPnode->_pRight == pParent)
			{
				pPnode->_pRight = subR;
				subR->_pParent = pPnode;
			}
		}
		//更新平衡因子
		pParent->_bf = subR->_bf = 0;
	}

左右双旋

右左双旋(不是单独的左右有一方低,有一方高)

(1)第一种情况,也是最特殊的情况,即parent的右子树只有两个节点

在这里插入图片描述

(2)第二种情况,parent的左右子树是高度为h的抽象子树,新增节点插入到b子树上

在这里插入图片描述

(2)第三种情况,parent的左右子树是高度为h的抽象子树,新增节点插入到c子树上 实际上第二三种情况的分析是一致的

在这里插入图片描述

void RotateLR(Node* pParent)
	{
		Node* subL = pParent->_pLeft;
		Node* subLR = subL->_pRight;
		int bf = subLR->_bf;
		//复用
		RotateL(subL);
		RotateR(pParent);
		//更新平衡因子
		//插入右边
		if (bf == 1)
		{
			subLR->_bf = 0;
			subL->_bf = -1;
			pParent->_bf = 0;
		}
		//插入左边
		else if (bf == -1)
		{
			subLR->_bf = 0;
			subL->_bf = 0;
			pParent->_bf = 1;
		}
		else if (bf == 0)
		{
			subLR->_bf = 0, subL->_bf = 0, pParent->_bf = 0;
		}
		else
		{
			assert(false);
		}
	}

右左双旋

左右双旋(不是单独的左右有一方低,有一方高)

(1)第一种情况,也是最特殊的情况,即parent的左子树只有两个节点

在这里插入图片描述

(2)第二种情况,parent的左右子树是高度为h的抽象子树,新增节点插入到c子树上

在这里插入图片描述

(3
)第三种情况,parent的左右子树是高度为h的抽象子树,新增节点插入到b子树上 实际上第二三种情况的分析是一致的

在这里插入图片描述

void RotateRL(Node* pParent)
	{
		Node* subR = pParent->_pRight;
		Node* subRL = subR->_pLeft;
		int bf = subRL->_bf;
		RotateR(subR);
		RotateL(pParent);
		//更新平衡因子
		//插入在右边
		if (bf == 1)
		{
			subRL->_bf = 0;
			subR->_bf = 0;
			pParent->_bf = -1;
		}
		//插入在左边
		else if (bf == -1)
		{
			subRL = 0;
			pParent->_bf = 0;
			subR->_bf = 1;
		}
		else if (bf == 0)
		{
			subRL =pParent->_bf = subR->_bf = 0;
		}
		else
		{
			assert(false);
		}
	}

测试

	size_t _Height(Node* pRoot)
	{
		if (pRoot == nullptr)
		{
			return 0;
		}
		int leftHeight = _Height(pRoot->_pLeft);
		int rightHeight = _Height(pRoot->_pRight);
		return (leftHeight > rightHeight) ? leftHeight + 1 : rightHeight + 1;
	}
	bool _IsBalance(Node* pRoot)
	{
		if (pRoot == nullptr)
		{
			return true;
		}
		int leftHeight = _Height(pRoot->_pLeft);
		int rightHeight = _Height(pRoot->_pRight);
		//平衡因子异常的情况
		if (rightHeight - leftHeight != pRoot->_bf)
		{
			cout << pRoot->_data << "平衡因子异常" << endl;
			return false;
		}
		//检查是否平衡
		return abs(rightHeight - leftHeight) < 2
			//检查、遍历左右子树
			&& _IsBalance(pRoot->_pLeft)
			&& _IsBalance(pRoot->_pRight);
	}
	bool IsBalance()
	{
		return _IsBalance(_pRoot);
	}
	int main()
{
	const int N = 30000;
	vector<int> v;
	v.reserve(N);
	srand(time(0));

	for (size_t i = 0; i < N; i++)
	{
		v.push_back(rand());
		cout << v.back() << endl;
	}
	AVLTree<int> t;
	for (auto e : v)
	{
		if (e == 41)
		{
			t.Insert(e);
		}
		cout << "Insert:" << e << "->" << t.IsBalance() << endl;
	}

	cout << t.IsBalance() << endl;

	return 0;
}

全部代码

template<class T>
struct AVLTreeNode
{
	AVLTreeNode(const T& data = T())
		: _pLeft(nullptr)
		, _pRight(nullptr)
		, _pParent(nullptr)
		, _data(data)
		, _bf(0)
	{}

	AVLTreeNode<T>* _pLeft;
	AVLTreeNode<T>* _pRight;
	AVLTreeNode<T>* _pParent;
	T _data;
	int _bf;   // 节点的平衡因子
};


// AVL: 二叉搜索树 + 平衡因子的限制
template<class T>
class AVLTree
{
	typedef AVLTreeNode<T> Node;
public:
	AVLTree()
		: _pRoot(nullptr)
	{}

	// 在AVL树中插入值为data的节点
	bool Insert(const T& data)
	{
		Node* cur = _pRoot;
		Node* parent = nullptr;
		//判断是否为空树
		if (_pRoot == nullptr)
		{
			//直接插入
			_pRoot = new Node(data);
			//插入成功
			return true;
		}

		//寻找插入位置
		else
		{
			Node* parent = cur;
			while (cur)
			{
				//记录父节点的位置,便于后续的链接操作
				parent = cur;
				//向左遍历
				if (cur->_data > data)
				{
					cur = cur->_pLeft;
				}
				//向右遍历
				else if (cur->_data < data)
				{
					cur = cur->_pRight;
				}
				//已有
				else return false;
			}
			cur = new Node(data);
			//插入+链接
			if (parent->_data > data)
			{
				parent->_pLeft = cur;
			}
			else
			{
				parent->_pRight = cur;
			}
			//链接
			cur->_pParent = parent;
		}
		//更新平衡因子
		while (parent)
		{
			if (cur == parent->_pRight)
			{
				parent->_bf++;
			}
			else if (cur == parent->_pLeft)
			{
				parent->_bf--;
			}

			if (parent->_bf == 0)
			{
				//插入后子树稳定,不用向上更新平衡因子
				return true;
			}
			else if (parent->_bf == 1 || parent->_bf == -1)
			{
				return true;
			}
			else if (parent->_bf == 2 || parent->_bf == -2)
			{
				if (parent->_bf == 2 && cur->_bf == 1)
				{
					//左旋 (右高左低,往左边压)
					RotateL(parent);
				}
				else if (parent->_bf == -2 && cur->_bf == -1)
				{
					//右旋(左高右低,往右边压)
					RotateR(parent);
				}
				else if (parent->_bf == 2 && cur->_bf == -1)
				{
					//右左双旋(不是单独的左右有一方低,有一方高)
					RotateL(parent);
				}
				else if (parent->_bf == -2 && cur->_bf == 1)
				{
					//左右双旋(不是单独的左右有一方低,有一方高)
					RotateR(parent);
				}
				parent = parent->_pParent;
				cur = cur->_pParent; 
				return true;
			}
			else
			{
				return false;
			}	
		}
		return true;
	}

	
	// AVL树的验证
	bool IsAVLTree()
	{
		return _IsAVLTree(_pRoot);
	}
	void _InOrder(Node* root)
	{
		if (root == nullptr)
		{
			return;
		}
		_InOrder(root->_pLeft);
		cout << root->_data << " ";
		_InOrder(root->_pRight);
	}
	void InOrder()
	{
		_InOrder(_pRoot);
		cout << endl;
	}
	// 根据AVL树的概念验证pRoot是否为有效的AVL树
	size_t _Height(Node* pRoot)
	{
		if (pRoot == nullptr)
		{
			return 0;
		}
		int leftHeight = _Height(pRoot->_pLeft);
		int rightHeight = _Height(pRoot->_pRight);
		return (leftHeight > rightHeight) ? leftHeight + 1 : rightHeight + 1;
	}
	bool _IsBalance(Node* pRoot)
	{
		if (pRoot == nullptr)
		{
			return true;
		}
		int leftHeight = _Height(pRoot->_pLeft);
		int rightHeight = _Height(pRoot->_pRight);
		//平衡因子异常的情况
		if (rightHeight - leftHeight != pRoot->_bf)
		{
			cout << pRoot->_data << "平衡因子异常" << endl;
			return false;
		}
		//检查是否平衡
		return abs(rightHeight - leftHeight) < 2
			//检查、遍历左右子树
			&& _IsBalance(pRoot->_pLeft)
			&& _IsBalance(pRoot->_pRight);
	}
	bool IsBalance()
	{
		return _IsBalance(_pRoot);
	}
	// 右单旋
	void RotateR(Node* pParent)
	{
		Node* pPnode = pParent->_pParent;
		Node* subL = pParent->_pLeft;
		Node* subLR = subL->_pRight;
		if (subLR)
		{
			pParent->_pLeft = subL->_pRight;
			subL->_pParent = pParent;
		}
		subL->_pRight = pParent;
		pParent->_pParent = subL;
		//旋转部分子树
		if (pPnode)
		{
			if (pPnode->_pLeft == pParent)
			{
				pPnode->_pLeft = subL;
				subL->_pParent = pPnode;
			}
			else
			{
				pPnode->_pLeft = subL;
				subL->_pParent = pPnode;
			}
		}
		//旋转整棵子树
		else
		{
			_pRoot = subL;
			subL->_pParent = nullptr;
		}
		//调节平衡因子
		pParent->_bf = subL->_bf = 0;
	}
	// 左单旋
	void RotateL(Node* pParent)
	{
		Node* pPnode = pParent->_pParent;
		Node* subR = pParent->_pRight;
		Node* subRL = subR->_pLeft;
		if (subRL)
		{
			pParent->_pRight = subRL;
			subRL->_pParent = pParent;
		}
		subR->_pLeft = pParent;
		pParent->_pParent = subR;

		//链接:旋转整棵树
		if (pPnode == nullptr)
		{
			_pRoot = subR;
			subR->_pParent = nullptr;
		}
		//链接:旋转子树
		else
		{
			if (pPnode->_pLeft == pParent)
			{
				pPnode->_pLeft = subR;
				subR->_pParent = pPnode;
			}
			else if (pPnode->_pRight == pParent)
			{
				pPnode->_pRight = subR;
				subR->_pParent = pPnode;
			}
		}
		//更新平衡因子
		pParent->_bf = subR->_bf = 0;
	}
	// 右左双旋
	void RotateRL(Node* pParent)
	{
		Node* subR = pParent->_pRight;
		Node* subRL = subR->_pLeft;
		int bf = subRL->_bf;
		RotateR(subR);
		RotateL(pParent);
		//更新平衡因子
		//插入在右边
		if (bf == 1)
		{
			subRL->_bf = 0;
			subR->_bf = 0;
			pParent->_bf = -1;
		}
		//插入在左边
		else if (bf == -1)
		{
			subRL = 0;
			pParent->_bf = 0;
			subR->_bf = 1;
		}
		else if (bf == 0)
		{
			subRL =pParent->_bf = subR->_bf = 0;
		}
		else
		{
			assert(false);
		}
	}
	// 左右双旋
	void RotateLR(Node* pParent)
	{
		Node* subL = pParent->_pLeft;
		Node* subLR = subL->_pRight;
		int bf = subLR->_bf;
		RotateL(subL);
		RotateR(pParent);
		//更新平衡因子
		//插入右边
		if (bf == 1)
		{
			subLR->_bf = 0;
			subL->_bf = -1;
			pParent->_bf = 0;
		}
		//插入左边
		else if (bf == -1)
		{
			subLR->_bf = 0;
			subL->_bf = 0;
			pParent->_bf = 1;
		}
		else if (bf == 0)
		{
			subLR->_bf = 0, subL->_bf = 0, pParent->_bf = 0;
		}
		else
		{
			assert(false);
		}
	}
private:
	Node* _pRoot;
};

//int main()
//{
//	//int a[] = { 16, 3, 7, 11, 9, 26, 18, 14, 15};
//	int a[] = { 4,2,6,13,5,15,7,16,14 };
//	AVLTree<int> t;
//	for (auto e : a)
//	{
//		t.Insert(e);
//	}
//	t.InOrder();
//	return 0;
//}
int main()
{
	const int N = 30000;
	vector<int> v;
	v.reserve(N);
	srand(time(0));

	for (size_t i = 0; i < N; i++)
	{
		v.push_back(rand());
		cout << v.back() << endl;
	}
	AVLTree<int> t;
	for (auto e : v)
	{
		if (e == 41)
		{
			t.Insert(e);
		}
		cout << "Insert:" << e << "->" << t.IsBalance() << endl;
	}

	cout << t.IsBalance() << endl;

	return 0;
}

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

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

相关文章

【Feign】 基于 Feign 远程调用、 自定义配置、性能优化、实现 Feign 最佳实践

&#x1f40c;个人主页&#xff1a; &#x1f40c; 叶落闲庭 &#x1f4a8;我的专栏&#xff1a;&#x1f4a8; SpringCloud MybatisPlus JVM 石可破也&#xff0c;而不可夺坚&#xff1b;丹可磨也&#xff0c;而不可夺赤。 Feign 一、 基于 Feign 远程调用1.1 RestTemplate方式…

PyTorch神经网络-激励函数

在PyTorch 神经网络当中&#xff0c;使用激励函数处理非线性的问题&#xff0c;普通的神经网络出来的数据一般是线性的关系&#xff0c;但是遇到比较复杂的数据的话&#xff0c;需要激励函数处理一些比较难以处理的问题&#xff0c;非线性结果就是其中的情况之一。 FAQ:为什么要…

高精度算法【Java】(待更新中~)

高进度加法 在Java中可以使用BigInteger进行高精度计算&#xff0c;除此也可以仿照竖式相加的计算原理进行计算。 BigInteger 提供所有 Java 的基本整数操作符的对应物&#xff0c;并提供 java.lang.Math 的所有相关方法。另外&#xff0c;BigInteger 还提供以下运算&#xff1…

全新酷盒9.0源码:多功能工具箱软件的最新iapp解决方案

全能工具箱软件酷盒&#xff1a;源码提供iapp解决方案&#xff0c;自定义打造个性化体验 酷盒是一款功能丰富的工具箱软件&#xff0c;内置众多实用功能&#xff0c;并实时更新热门功能。该软件还拥有丰富的资源库&#xff0c;用户可以在线畅玩游戏、免费下载音乐等。 我们提…

【Django-DRF用法】多年积累md笔记,第(4)篇:Django-DRF反序列化详解

本文从分析现在流行的前后端分离Web应用模式说起&#xff0c;然后介绍如何设计REST API&#xff0c;通过使用Django来实现一个REST API为例&#xff0c;明确后端开发REST API要做的最核心工作&#xff0c;然后介绍Django REST framework能帮助我们简化开发REST API的工作。 全…

C++基础从0到1入门编程(三)

系统学习C 方便自己日后复习&#xff0c;错误的地方希望积极指正 往期文章&#xff1a; C基础从0到1入门编程&#xff08;一&#xff09; C基础从0到1入门编程&#xff08;二&#xff09; 参考视频&#xff1a; 1.黑马程序员匠心之作|C教程从0到1入门编程,学习编程不再难 2.系统…

开源与闭源:大模型发展的双重走向

目录 前言开源和闭源的优劣势比较开源的优势闭源的优势 开源和闭源对大模型技术发展的影响对技术发展的影响对数据共享的影响对业务拓展的影响 开源与闭源的商业模式比较开源的商业模式闭源的商业模式 处在大模型洪流中&#xff0c;向何处去&#xff1f;结语 前言 随着人工智能…

python趣味编程-5分钟实现一个俄罗斯方块游戏(含源码、步骤讲解)

Python俄罗斯方块游戏是一款基于GUI的标题匹配益智游戏,非常容易理解和使用。说到游戏玩法,一切都和真实的一样。 用户必须管理俄罗斯方块的随机序列。在这个Python 俄罗斯方块游戏项目中,我将教您如何使用 Python 制作俄罗斯方块游戏。 Python 代码中的俄罗斯方块游戏:项目…

如何在虚拟机的Ubuntu22.04中设置静态IP地址

为了让Linux系统的IP地址在重新启动电脑之后IP地址不进行变更&#xff0c;所以将其IP地址设置为静态IP地址。 查看虚拟机中虚拟网络编辑器获取当前的子网IP端 修改文件/etc/netplan/00-installer-config.yaml文件&#xff0c;打开你会看到以下内容 # This is the network conf…

开源WIFI继电器之硬件电路

一、原理图 源文件 二、原理图说明 1、器件说明 U4&#xff1a;ESP8285模块 U6&#xff1a;触发器 U3&#xff1a;继电器 2、继电器状态检测说明 检测继电器线圈是否通电来判断继电器是否导通&#xff0c;当Q1不导通时&#xff0c;Q1集电极的电压为3.3V&#xff0c;经…

【运维篇】Redis常见运维命令详解

文章目录 1. 前言2. 连接管理命令详解2.1 AUTH命令2.2 PING命令2.3 SELECT命令2.4 QUIT命令 3. 服务器管理命令详解3.1 FLUSHALL命令3.2 SAVE/BGSAVE命令3.3 SHUTDOWN命令 4. 安全管理命令详解4.1 CONFIG命令4.1.1 CONFIG SET命令用法4.1.2 CONFIG GET命令用法 4.2 AUTH命令 5.…

T10 数据增强

文章目录 一、准备环境和数据1.环境2. 数据 二、数据增强&#xff08;增加数据集中样本的多样性&#xff09;三、将增强后的数据添加到模型中四、开始训练五、自定义增强函数六、一些增强函数 &#x1f368; 本文为&#x1f517;365天深度学习训练营 中的学习记录博客&#x1f…

【算法】滑动窗口题单——2.不定长滑动窗口(求最长/最大)

文章目录 3. 无重复字符的最长子串1493. 删掉一个元素以后全为 1 的最长子数组904. 水果成篮1695. 删除子数组的最大得分2841. 几乎唯一子数组的最大和2024. 考试的最大困扰度1004. 最大连续1的个数 III1438. 绝对差不超过限制的最长连续子数组2401. 最长优雅子数组解法1——维…

[AutoSar]导出task mapping 表到excel

目录 关键词平台说明背景实现方法 关键词 嵌入式、C语言、autosar 平台说明 项目ValueOSautosar OSautosar厂商vector芯片厂商TI编程语言C&#xff0c;C编译器HighTec (GCC) 背景 为了做文档输出&#xff0c;要导出task mapping 到excel。 实现方法 1.按住shift&#xf…

IDEA自动注解设置(中文版)

IDEA自动注解设置 1、添加类自动注释 文件 - 设置 - 编辑器 - 文件和代码模板 - Include - File Header /** *description&#xff1a;TODO *author&#xff1a; ${USER} *create&#xff1a; ${DATE} ${TIME} */2、添加类方法自动注释 文件 - 设置 - 编辑器 - 实时模版 - …

NSS [NCTF 2018]小绿草之最强大脑

NSS [NCTF 2018]小绿草之最强大脑 题目要求我们输入一个位数>21的正数&#xff0c;带入表达式并且计算结果。 查看源码发现hint&#xff0c;有源码泄露。 拿dirsearch扫一下。扫到了一个备份文件。 python dirsearch.py -u http://node4.anna.nssctf.cn:28805/访问/index.…

SpringCloud 微服务全栈体系(十四)

第十一章 分布式搜索引擎 elasticsearch 四、RestAPI ES 官方提供了各种不同语言的客户端&#xff0c;用来操作 ES。这些客户端的本质就是组装 DSL 语句&#xff0c;通过 http 请求发送给 ES。官方文档地址&#xff1a;https://www.elastic.co/guide/en/elasticsearch/client/…

H110主板搭配魔改QNCW升级小记

最近搬家完毕&#xff0c;翻出来一块闲置已久的qncw&#xff0c;隐约记得是买的主板套装&#xff0c;现在主板早已不知踪影&#xff0c;剩下孤零零一个CPU&#xff0c;一起翻出来一个G3900T亮机CPU&#xff0c;应该是同时代的产物。 qncw百度上一搜&#xff0c;发现参数还行&am…

iTerm2+oh-my-zsh搭个Mac电脑上好用好看终端

根据苹果网站上介绍&#xff0c;bash是 macOS Mojave 及更早版本中的默认Shell&#xff0c;从 macOS Catalina 开始&#xff0c;zsh(Z shell) 是所有新建用户帐户的默认Shell。 1. 安装Oh my zsh sh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzs…

代码随想录算法训练营第二十八天| 78 子集 90 子集|| 93 复原IP地址

78 子集 由题意可知数组中的元素互不相同&#xff0c;所以在dfs中我们可以将当前的path直接加入到res中。 class Solution {List<List<Integer>>res new ArrayList<>();List<Integer>path new LinkedList<>();public List<List<Integer…
最新文章