当前位置: 首页 > news >正文

【数据结构】AVL树

AVL树

  • 一、AVL树的概念
  • 二、AVL的接口
    • 2.1 插入
    • 2.2 旋转
      • 2.2.1 左单旋
      • 2.2.2 右单旋
      • 2.2.3 左右双旋
      • 2.2.4 右左双旋
  • 三、验证
  • 四、源码

一、AVL树的概念

当我们用普通的搜索树插入数据的时候,如果插入的数据是有序的,那么就退化成了一个链表,搜索效率低下。

为了应对这种情况,就出现了AVL树(高度平衡二叉搜索树):

当向二叉搜索树中插入新结点后,如果能保证每个结点的左右子树高度之差的绝对值不超过1

AVL树的性质:

  • 它的左右子树都是AVL树。
  • 左右子树高度之差(简称平衡因子)的绝对值不超过1

平衡因子= 右子树高度-左子树高度

在这里插入图片描述
平衡因子是用来检测树的状态,如果平衡因子都在(-1, 0, 1)中,则没问题,反之则需要调整。

二、AVL的接口

AVL的节点定义:

template <class K, class V>
struct AVLNode
{AVLNode(const pair<K, V>& kv): _kv(kv), _left(nullptr), _right(nullptr), _parent(nullptr), _bf(0){}pair<K, V> _kv;AVLNode<K, V>* _left;AVLNode<K, V>* _right;AVLNode<K, V>* _parent;int _bf;// 平衡因子
};

2.1 插入

AVL的基本插入流程跟搜索树相似,但是AVL树多了一个平衡因子。
一旦插入新节点,就要往上更新平衡因子

  • 如果是在左边点插入,则平衡因子--
  • 如果是在右边点插入,则平衡因子++

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
更新一个结点之后我们需要去进行判断,子树的高度是否发生了变化:

1️⃣ 当父节点的平衡因子变成0:说明原来是-1或1,那么也就是把矮的地方填平了,父节点所在树的高度不变,不需要继续更新
2️⃣ 当父节点的平衡因子变成1或-1:说明原来是0,父节点所在树的高度发生变化,需要继续更新
3️⃣ 当当父节点的平衡因子变成2或-2违反规则,需要进行旋转处理

所以我们可以利用parent节点(插入之前的叶子节点),从它开始往上更新。

bool insert(const pair<K, V>& kv)
{if (_root == nullptr){_root = new Node(kv);return true;}Node* parent = nullptr;Node* cur = _root;while (cur){if (kv.first < cur->_kv.first){parent = cur;cur = cur->_left;}else if (kv.first > cur->_kv.first){parent = cur;cur = cur->_right;}else return false;}cur = new Node(kv);if (kv.first < parent->_kv.first){parent->_left = cur;}else{parent->_right = cur;}cur->_parent = parent;// 更新平衡因子while (parent){if (cur == parent->_left) parent->_bf--;else parent->_bf++;if (parent->_bf == 0) break;else if (parent->_bf == 1 || parent->_bf == -1){cur = parent;parent = parent->_parent;}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){// 左右双旋RotateLR(parent);}else if (parent->_bf == 2 && cur->_bf == -1){// 右左双旋RotateRL(parent);}break;}else{cout << "结构出错" << endl;assert(false);}}return true;
}

2.2 旋转

为了保证每个结点的左右子树高度之差的绝对值不超过1,所以当平衡因子变为-2或2时,需要旋转来保持平衡。
旋转规则:
1️⃣ 让这颗子树左右高度差不超过1
2️⃣ 旋转过程中继续保持它是搜索树
3️⃣ 更新调整孩子节点的平衡因子
4️⃣ 让这颗子树的高度根插入前保持一致

2.2.1 左单旋

二叉树的结构有无数种情况,所以我们需要总结出抽象图来分析
在这里插入图片描述
解释:
a/b/c是高度为h的AVL树。

新节点插入较高右子树的右侧—右右:左单旋
在这里插入图片描述
左单旋的步骤:

1️⃣ 20的左边调整到10的右边
2️⃣ 10变成20的左边,20做根
3️⃣ 把平衡因子变为0

在这里插入图片描述

void RotateL(Node* parent)
{Node* top = parent->_parent;Node* right = parent->_right;// 20的左边调整到10的右边parent->_right = right->_left;if (right->_left) right->_left->_parent = parent;// 10变成20的左边,20做根right->_left = parent;parent->_parent = right;if (top)// 子树{if (parent == top->_left) top->_left = right;else top->_right = right;right->_parent = top;}else// 完整的树{_root = right;_root->_parent = nullptr;}// 更新平衡因子parent->_bf = right->_bf = 0;
}

2.2.2 右单旋

新节点插入较高左子树的左侧—左左:右单旋
在这里插入图片描述在这里插入图片描述

void RotateR(Node* parent)
{Node* top = parent->_parent;Node* left = parent->_left;Node* leftR = left->_right;parent->_left = leftR;if (leftR) leftR->_parent = parent;left->_right = parent;parent->_parent = left;if (top){if (parent == top->_left) top->_left = left;else top->_right = left;left->_parent = top;}else{_root = left;_root->_parent = nullptr;}parent->_bf = left->_bf = 0;
}

2.2.3 左右双旋

新节点插入较高左子树的右侧—左右:先左单旋再右单旋

我们看到上面的单旋,我们会想,如果是这么插入呢?
在这里插入图片描述

其实这个图可以转化为:

在这里插入图片描述
先以10为轴进行左单旋,这样就把“折线”变成了直线,在以20为轴进行右单旋。
在这里插入图片描述
这里就要注意平衡因子的更新
15的平衡因子为0
但是其他两个会有三个不同的情况:

1️⃣ 当right的平衡因子为-1时(插入在b),双旋结束后parent、left、right的平衡因子分别更新为1、0、0
在这里插入图片描述
2️⃣ 当right的平衡因子为1时(插入在c),双旋结束后parent、left、right的平衡因子分别更新为0、-1、0
在这里插入图片描述
3️⃣ 当right的平衡因子为0时,双旋后parent、left、right的平衡因子分别更新为0、0、0
在这里插入图片描述

所以在旋转前要先进行判断在哪插入(通过平衡因子),旋转后手动更新即可。

void RotateLR(Node* parent)
{Node* left = parent->_left;Node* right = left->_right;int bf = right->_bf;// 提前记录RotateL(parent->_left);RotateR(parent);if (bf == -1)// 左子树新增{left->_bf = 0;right->_bf = 0;parent->_bf = 1;}else if (bf == 1)// 右子树新增{left->_bf = -1;right->_bf = 0;parent->_bf = 0;}else if (bf == 0)// 自己就是新增{left->_bf = right->_bf = parent->_bf = 0;}else assert(false);
}

2.2.4 右左双旋

	void RotateRL(Node* parent){Node* right = parent->_right;Node* left = right->_left;int bf = left->_bf;RotateR(right);RotateL(parent);if (bf == -1){parent->_bf = 0;left->_bf = 0;right->_bf = 1;}else if (bf == 1){right->_bf = 0;left->_bf = 0;parent->_bf = -1;}else if (bf == 0){left->_bf = right->_bf = parent->_bf = 0;}else assert(false);}

三、验证

为了验证是否为二叉搜索树,我们可以先写一个中序遍历

void _Inorder(Node* root)
{if (root == nullptr)return;_Inorder(root->_left);cout << root->_kv.first << ":" << root->_kv.second << endl;_Inorder(root->_right);
}void Inorder()
{_Inorder(_root);
}

为了验证是否为AVL树,我们要让每个节点的左右子树高度的绝对值差小于等于1。

int Height(Node* root)
{if (!root){return 0;}int lh = Height(root->_left) + 1;int rh = Height(root->_right) + 1;return max(lh, rh);
}bool IsBalance(Node* root)
{if (!root){return true;}int lh = Height(root->_left);int rh = Height(root->_right);if (rh - lh != root->_bf){cout << root->_kv.first << ":";cout << root->_bf << ":";cout << "平衡因子出错" << endl;return false;}if (abs(rh - lh) > 1){return false;}return IsBalance(root->_left) && IsBalance(root->_right);
}bool IsBalance()
{return IsBalance(_root);
}

我们可以用大量的随机值来测定:

void test()
{const int N = 100000;AVLTree<int, int> tt;srand(time(0));for (int i = 0; i < N; i++){int x = rand();tt.insert(make_pair(x, x));}//tt.Inorder();cout << tt.IsBalance() << endl;
}

四、源码

#pragma once
#include <iostream>
#include <string>
#include <cassert>
#include <cstdlib> using namespace std;template <class K, class V>
struct AVLNode
{AVLNode(const pair<K, V>& kv): _kv(kv), _left(nullptr), _right(nullptr), _parent(nullptr), _bf(0){}pair<K, V> _kv;AVLNode<K, V>* _left;AVLNode<K, V>* _right;AVLNode<K, V>* _parent;int _bf;// 平衡因子
};template <class K, class V>
class AVLTree
{typedef AVLNode<K, V> Node;
public:bool insert(const pair<K, V>& kv){if (_root == nullptr){_root = new Node(kv);return true;}Node* parent = nullptr;Node* cur = _root;while (cur){if (kv.first < cur->_kv.first){parent = cur;cur = cur->_left;}else if (kv.first > cur->_kv.first){parent = cur;cur = cur->_right;}else return false;}cur = new Node(kv);if (kv.first < parent->_kv.first){parent->_left = cur;}else{parent->_right = cur;}cur->_parent = parent;// 更新平衡因子while (parent){if (cur == parent->_left) parent->_bf--;else parent->_bf++;if (parent->_bf == 0) break;else if (parent->_bf == 1 || parent->_bf == -1){cur = parent;parent = parent->_parent;}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){// 左右双旋RotateLR(parent);}else if (parent->_bf == 2 && cur->_bf == -1){// 右左双旋RotateRL(parent);}break;}else{cout << "结构出错" << endl;assert(false);}}return true;}void RotateL(Node* parent){Node* top = parent->_parent;Node* right = parent->_right;// 20的左边调整到10的右边parent->_right = right->_left;if (right->_left) right->_left->_parent = parent;// 10变成20的左边,20做根right->_left = parent;parent->_parent = right;if (top)// 子树{if (parent == top->_left) top->_left = right;else top->_right = right;right->_parent = top;}else// 完整的树{_root = right;_root->_parent = nullptr;}// 更新平衡因子parent->_bf = right->_bf = 0;}void RotateR(Node* parent){Node* top = parent->_parent;Node* left = parent->_left;Node* leftR = left->_right;parent->_left = leftR;if (leftR) leftR->_parent = parent;left->_right = parent;parent->_parent = left;if (top){if (parent == top->_left) top->_left = left;else top->_right = left;left->_parent = top;}else{_root = left;_root->_parent = nullptr;}parent->_bf = left->_bf = 0;}void RotateLR(Node* parent){Node* left = parent->_left;Node* right = left->_right;int bf = right->_bf;// 提前记录RotateL(left);RotateR(parent);if (bf == -1)// 左子树新增{left->_bf = 0;right->_bf = 0;parent->_bf = 1;}else if (bf == 1)// 右子树新增{left->_bf = -1;right->_bf = 0;parent->_bf = 0;}else if (bf == 0)// 自己就是新增{left->_bf = right->_bf = parent->_bf = 0;}else assert(false);}void RotateRL(Node* parent){Node* right = parent->_right;Node* left = right->_left;int bf = left->_bf;RotateR(right);RotateL(parent);if (bf == -1){parent->_bf = 0;left->_bf = 0;right->_bf = 1;}else if (bf == 1){right->_bf = 0;left->_bf = 0;parent->_bf = -1;}else if (bf == 0){left->_bf = right->_bf = parent->_bf = 0;}else assert(false);}void _Inorder(Node* root){if (root == nullptr)return;_Inorder(root->_left);cout << root->_kv.first << "<=>" << root->_kv.second << endl;_Inorder(root->_right);}void Inorder(){_Inorder(_root);}int Height(Node* root){if (!root){return 0;}int lh = Height(root->_left) + 1;int rh = Height(root->_right) + 1;return max(lh, rh);}bool IsBalance(Node* root){if (!root){return true;}int lh = Height(root->_left);int rh = Height(root->_right);if (rh - lh != root->_bf){cout << root->_kv.first << ":";cout << root->_bf << ":";cout << "平衡因子出错" << endl;return false;}if (abs(rh - lh) > 1){return false;}return IsBalance(root->_left) && IsBalance(root->_right);}bool IsBalance(){return IsBalance(_root);}
private:Node* _root = nullptr;
};void test()
{const int N = 100000;AVLTree<int, int> tt;srand(time(0));for (int i = 0; i < N; i++){int x = rand();tt.insert(make_pair(x, x));}//tt.Inorder();cout << tt.IsBalance() << endl;
}

相关文章:

【数据结构】AVL树

AVL树一、AVL树的概念二、AVL的接口2.1 插入2.2 旋转2.2.1 左单旋2.2.2 右单旋2.2.3 左右双旋2.2.4 右左双旋三、验证四、源码一、AVL树的概念 当我们用普通的搜索树插入数据的时候&#xff0c;如果插入的数据是有序的&#xff0c;那么就退化成了一个链表&#xff0c;搜索效率…...

这一次我不再低调,老板法拉利的车牌有我的汗水

起源: 5Why分析法最初是由丰田佐吉提出的,后来,丰田汽车公司在发展完善其制造方法学的过程中持续采用该方法。5Why分析法作为丰田生产系统的入门课程之一,是问题求解的关键培训课程。丰田生产系统的设计师大野耐一曾将5Why分析法描述为:“丰田科学方法的基础,重复五次,问…...

通过连接另一个数组的子数组得到一个数组

给你一个长度为 n 的二维整数数组 groups &#xff0c;同时给你一个整数数组 nums 。 你是否可以从 nums 中选出 n 个 不相交 的子数组&#xff0c;使得第 i 个子数组与 groups[i] &#xff08;下标从 0 开始&#xff09;完全相同&#xff0c;且如果 i > 0 &#xff0c;那么…...

公派访问学者的申请条件

知识人网海外访问学者申请老师为大家分享公派访问学者申请的基本条件以及哪些人员的申请是暂不受理的&#xff0c;供大家参考&#xff1a;一、 申请人基本条件&#xff1a;1.热爱社会主义祖国&#xff0c;具有良好的思想品德和政治素质&#xff0c;无违法违纪记录。2.具有良好专…...

多点电容触摸屏实验

目录 一、简介 二、硬件原理 ​编辑1、CT_INT 2、I2C2_SCL和I2C2_SDA 3、RESET复位引脚 三、FT54x6/FT52x6电容触摸芯片 四、代码编写 1、编写ft5426.h 2、编写ft5426.c 3、main函数 一、简介 电容屏只需要手指轻触即可&#xff0c;而电阻屏是需要手指给予一定的压力才…...

【算法与数据结构(C语言)】栈和队列

文章目录 目录 前言 一、栈 1.栈的概念及结构 2.栈的实现 入栈 出栈 获取栈顶元素 获取栈中有效元素个数 检测栈是否为空&#xff0c;如果为空返回非零结果&#xff0c;如果不为空返回0 销毁栈 二、队列 1.队列的概念及结构 2.队列的实现 初始化队列 队尾入队列 队头出队列 获…...

Uni-app使用vant和uview组件

目录 1.安装vant组件 1.1安装前需知 1.2.安装 1.3.创建uni-app项目 2.安装uview-ui组件 2.1官网 2.2安装 2.3安装成功 1.安装vant组件 1.1安装前需知 小程序能使用vant-weapp组件&#xff0c;且官网的安装是直接导入小程序中&#xff0c;不能直接导入uni-app框架中 V…...

2023年PMP考试应该注意些什么?

首先注意&#xff08;报考条件&#xff09; 2023年PMP考试报名流程&#xff1a; 一、PMP英文报名&#xff1a; 英文报名时间无限制&#xff0c;随时可以报名&#xff0c;但有一年的有效期&#xff0c;所以大家尽量提前报名&#xff0c;在英文报名有效期内进行中文报名。 英…...

selenium环境安装及使用

selenium简介官网https://www.selenium.dev简介用于web浏览器测试的工具支持的浏览器包括IE&#xff0c;Firefox,Chrome&#xff0c;edge等使用简单&#xff0c;可使用java&#xff0c;python等多种语言编写用例脚本主要由三个工具构成&#xff0c;webdriver,IDE,web自动化环境…...

高性能低功耗4口高速USB2.0 HUB 完美替代FE1.1S和FE8.1

该NS1.1s是一个高度集成的&#xff0c;高品质&#xff0c;高性能&#xff0c;低功耗&#xff0c;为USB 2.0高速4端口集线器又低成本的解决方案。 &#xff08;点击即可咨询芯片详细信息&#xff09; NS1.1s的特点 1.通用串行总线规范修订版2.0&#xff08;USB 2.0&#xff09;完…...

Go全栈学习(一)基础语法

Go语言基础语法 文章目录Go语言基础语法注释变量变量的定义变量的交换理解变量&#xff08;内存地址&#xff09;匿名变量变量的作用域常量2023.2.4日 总结// 关于Goland 中 执行的问题// 1、包下执行 &#xff08;一个 main 函数来执行&#xff0c;如果有多个&#xff0c;无法…...

centos7搭建svn配置

基本概述 Apache Subversion&#xff08;简称SVN&#xff0c;svn&#xff09;&#xff0c;一个开放源代码的版本控制系统&#xff0c;相较于RCS、CVS&#xff0c;它采用了分支管理系统&#xff0c;它的设计目标就是取代CVS。互联网上很多版本控制服务已从CVS转移到Subversion。…...

趣味三角——第12章——tanx

第12章节 tanx In his very numerous memoires, and especially in his great work, Introductio in analysin infinitorum (1748), Euler displayed the most wonderful skill in obtaining a rich harvest of results of great interest. . . . Hardly any other work …...

Java - 数据结构,栈

一、栈 1.1、什么是栈 栈&#xff1a;一种特殊的线性表&#xff0c;其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端称为栈 顶&#xff0c;另一端称为栈底。栈中的数据元素遵守后进先出LIFO&#xff08;Last In First Out&#xff09;的原则。 压…...

某餐厅系统网络故障分析案例

背景 针对食堂经营企业&#xff0c;某堂食软件为客户提供优化堂食就餐流程、提高食堂服务水平和管理效率。 某上海客户使用该堂食系统&#xff0c;在就餐高峰时段&#xff0c;总是出现支付、点餐等操作缓慢&#xff0c;动辄一个操作需要等待几十秒。该客户联系软件厂商&#…...

华为OD机试题,用 Java 解【密室逃生游戏】问题

最近更新的博客 华为OD机试 - 猴子爬山 | 机试题算法思路 【2023】华为OD机试 - 分糖果(Java) | 机试题算法思路 【2023】华为OD机试 - 非严格递增连续数字序列 | 机试题算法思路 【2023】华为OD机试 - 消消乐游戏(Java) | 机试题算法思路 【2023】华为OD机试 - 组成最大数…...

如何重命名SQL Server数据库

重命名SQL Server数据库 使用T-SQL重命名SQL Server数据库使用分离和附加重命名SQL Server数据库使用T-SQL查询分离和重新连接在SSMS中分离和重新连接通过SSMS重命名SQL Server数据库当使用SQL数据库很长一段时间时,你可能会遇到需要为数据库命名的情况。它可以用几种不同的方…...

联想昭阳E5-ITL电脑开机后绿屏怎么U盘重装系统?

联想昭阳E5-ITL电脑开机后绿屏怎么U盘重装系统&#xff1f;有用户电脑正常开机之后&#xff0c;出现了屏幕变成绿屏&#xff0c;无法进行操作的情况。这个问题是系统出现了问题&#xff0c;那么如何去进行问题的解决呢&#xff1f;接下来我们一起来分享看看如何使用U盘重装电脑…...

车载开发知识交流【学习路线】

前言 在2023国内百废待兴&#xff1b;经济复苏的号召一直在响应&#xff0c;这对于压抑了三年的人民来说无疑是福音。这篇我们主要说一下拉动经济的其中大板块——车企&#xff1b;我们知道我们最大的经济除了房地产&#xff0c;第二就是车企。而在造车领域中也不断的加入了许…...

【读书笔记】《深入浅出数据分析》第二章 检验你的理论

文章目录一&#xff0c;相关分析方法1&#xff0c;相关系数二&#xff0c;相关性不等于因果关系三&#xff0c;证明因果关系&#xff0c;“控制变量法”?本章主要说明了两个问题&#xff1a; 1&#xff0c;相关性不等于因果关系 2&#xff0c;如何判断两种数据之间是相关性&am…...

DockerHub与私有镜像仓库在容器化中的应用与管理

哈喽&#xff0c;大家好&#xff0c;我是左手python&#xff01; Docker Hub的应用与管理 Docker Hub的基本概念与使用方法 Docker Hub是Docker官方提供的一个公共镜像仓库&#xff0c;用户可以在其中找到各种操作系统、软件和应用的镜像。开发者可以通过Docker Hub轻松获取所…...

UE5 学习系列(三)创建和移动物体

这篇博客是该系列的第三篇&#xff0c;是在之前两篇博客的基础上展开&#xff0c;主要介绍如何在操作界面中创建和拖动物体&#xff0c;这篇博客跟随的视频链接如下&#xff1a; B 站视频&#xff1a;s03-创建和移动物体 如果你不打算开之前的博客并且对UE5 比较熟的话按照以…...

Cilium动手实验室: 精通之旅---20.Isovalent Enterprise for Cilium: Zero Trust Visibility

Cilium动手实验室: 精通之旅---20.Isovalent Enterprise for Cilium: Zero Trust Visibility 1. 实验室环境1.1 实验室环境1.2 小测试 2. The Endor System2.1 部署应用2.2 检查现有策略 3. Cilium 策略实体3.1 创建 allow-all 网络策略3.2 在 Hubble CLI 中验证网络策略源3.3 …...

如何将联系人从 iPhone 转移到 Android

从 iPhone 换到 Android 手机时&#xff0c;你可能需要保留重要的数据&#xff0c;例如通讯录。好在&#xff0c;将通讯录从 iPhone 转移到 Android 手机非常简单&#xff0c;你可以从本文中学习 6 种可靠的方法&#xff0c;确保随时保持连接&#xff0c;不错过任何信息。 第 1…...

Maven 概述、安装、配置、仓库、私服详解

目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...

JS设计模式(4):观察者模式

JS设计模式(4):观察者模式 一、引入 在开发中&#xff0c;我们经常会遇到这样的场景&#xff1a;一个对象的状态变化需要自动通知其他对象&#xff0c;比如&#xff1a; 电商平台中&#xff0c;商品库存变化时需要通知所有订阅该商品的用户&#xff1b;新闻网站中&#xff0…...

使用Spring AI和MCP协议构建图片搜索服务

目录 使用Spring AI和MCP协议构建图片搜索服务 引言 技术栈概览 项目架构设计 架构图 服务端开发 1. 创建Spring Boot项目 2. 实现图片搜索工具 3. 配置传输模式 Stdio模式&#xff08;本地调用&#xff09; SSE模式&#xff08;远程调用&#xff09; 4. 注册工具提…...

nnUNet V2修改网络——暴力替换网络为UNet++

更换前,要用nnUNet V2跑通所用数据集,证明nnUNet V2、数据集、运行环境等没有问题 阅读nnU-Net V2 的 U-Net结构,初步了解要修改的网络,知己知彼,修改起来才能游刃有余。 U-Net存在两个局限,一是网络的最佳深度因应用场景而异,这取决于任务的难度和可用于训练的标注数…...

华为OD最新机试真题-数组组成的最小数字-OD统一考试(B卷)

题目描述 给定一个整型数组,请从该数组中选择3个元素 组成最小数字并输出 (如果数组长度小于3,则选择数组中所有元素来组成最小数字)。 输入描述 行用半角逗号分割的字符串记录的整型数组,0<数组长度<= 100,0<整数的取值范围<= 10000。 输出描述 由3个元素组成…...

[拓扑优化] 1.概述

常见的拓扑优化方法有&#xff1a;均匀化法、变密度法、渐进结构优化法、水平集法、移动可变形组件法等。 常见的数值计算方法有&#xff1a;有限元法、有限差分法、边界元法、离散元法、无网格法、扩展有限元法、等几何分析等。 将上述数值计算方法与拓扑优化方法结合&#…...