【计算智能】基本遗传算法在优化问题中的应用与实验【理论到程序】

文章目录

  • 1. 引言:遗传算法简介
  • 2. 基本遗传算法(SGA)
    • 2.1 基本遗传算法的构成要素
      • 1. 染色体编码
      • 2. 适应度函数
      • 3. 遗传算子
    • 2.2 实验设计与方法
      • 1. 算法流程
      • 2. 伪代码
      • 3. python实现
        • 1. 导入模块
        • 2. 目标函数 f(x)
        • 3 初始化种群
        • 4. 计算适应度
        • 5. 选择操作:轮盘赌选择
        • 6. 单点交叉操作
        • 7. 变异操作
        • 8. 遗传算法
        • 9. 主程序
    • 2.3 实验结果与分析
    • 2.4 结论与展望
  • 3. 遗传算法的改进
  • 4. 遗传算法的应用
  • 5. 代码整合
    • 6. 随笔

摘要: 本文将介绍遗传算法在解决优化问题中的应用,并通过实验展示了遗传算法的基本原理和实现过程。选取一个简单的二次函数作为优化目标,利用遗传算法寻找其在指定范围内的最大值。

1. 引言:遗传算法简介

  遗传算法是一种启发式优化算法,模拟了生物进化的过程,通过选择、交叉和变异等操作来搜索解空间中的最优解或近似解,其在解决复杂的优化问题和搜索空间较大的问题时表现出色。

2. 基本遗传算法(SGA)

  基本遗传算法(Simple Genetic Algorithm : SGA)又称为简单遗传算法,只使用选择算子、交叉算子和变异算子这三种基本的遗传算子。其遗传操作简单、容易理解,是其它遗传算法的雏形和基础。

2.1 基本遗传算法的构成要素

  基本遗传算法由染色体编码方法、适应度函数和遗传算子三个主要要素组成。下面将对每个要素进行详细说明:

1. 染色体编码

  染色体编码方法指将问题的解空间映射到染色体上的过程。通常采用二进制编码方法,将问题的解表示为一个二进制串。例如,在解决一个优化问题时,可以将每个解编码为一个二进制串,其中每一位代表一个决策变量的取值。除了二进制编码,还可以使用整数编码、浮点数编码或字符编码,根据问题的特性选择合适的编码方法。

2. 适应度函数

  适应度函数(又称适应值/适应函数)用于评价染色体的优劣程度,即衡量染色体对问题解的贡献或适应程度。适应度函数的设计应与问题的特性密切相关,通常通过问题的目标函数来定义。例如,在优化问题中,适应度函数可以直接使用目标函数的值作为染色体的适应度,或根据问题的约束条件进行适当的调整。

3. 遗传算子

  遗传算子是基本遗传算法的核心组成部分,包括选择算子、交叉算子和变异算子。

  • 选择算子(Selection):又称复制算子,按照某种策略从父代中挑选个体进入下一代,常见的选择算子包括比例选择、轮盘赌选择、锦标赛选择等。
    • 选择算子的目标是按染色体的适应度进行选择,以保留适应度较高的个体,促进种群的进化。
  • 交叉算子(Crossover):又称杂交算子,用于从选定的父代染色体中产生子代染色体。常见的交叉算子包括单点交叉、多点交叉等。
    • 交叉算子通过交换染色体的部分信息产生新的个体,增加种群的多样性。
  • 变异算子(Mutation):用于对染色体的个别基因进行随机变化。
    • 变异算子的作用是引入种群的随机性,避免陷入局部最优解。常见的变异算子包括单点变异、均匀变异等,通常具有较小的概率,以保持种群的稳定性

  基本遗传算法能够模拟自然进化的过程,通过选择、交叉和变异等遗传操作逐步优化种群,求得问题的最优解或近似解。

2.2 实验设计与方法

1. 算法流程

Created with Raphaël 2.3.0 开始 初始化群体 适应值评价,保存最优染色体 选择 交配 变异 重新评价适应值,更新最优染色体 满足终止条件? 结束 yes no

2. 伪代码

Procedure GeneticAlgorithm()
    t = 0 // 初始化迭代次数
    InitializePopulation(P(t)) // 初始化种群
    Evaluate(P(t)) // 评估种群中个体的适应度
    Best = KeepBest(P(t)) // 保留当前最优个体

    while (not TerminationConditionMet()) do
        P(t) = Selection(P(t)) // 选择操作
        P(t) = Crossover(P(t)) // 交叉操作
        P(t) = Mutation(P(t))  // 变异操作
        t = t + 1 // 更新迭代次数
        P(t) = P(t-1)
        Evaluate(P(t)) // 重新评估种群中个体的适应度
        if (BestIndividual(P(t)) > Best) then
            Best = ReplaceBest(P(t)) // 更新最优个体
        end if
    end while

    return Best // 返回找到的最优解
End Procedure

3. python实现

  本实验选择了一个简单的二次函数 m a x f ( x ) = x 2 , x ∈ [ 0 , 31 ] max f(x) = x^2, x \in [0, 31] maxf(x)=x2,x[0,31] 作为优化目标:

  • 对函数的解空间进行二进制编码
  • 随机生成初始种群
  • 计算每个个体的适应度使用选择、交叉和变异操作优化种群,直到达到设定的迭代次数。
  • 评估最优解的适应度并输出结果。
1. 导入模块
import random
2. 目标函数 f(x)
def f(x):
    return x ** 2
3 初始化种群
def initialize_population(population_size, chromosome_length):
    return [bin(random.randint(0, 31))[2:].zfill(chromosome_length) for _ in range(population_size)]

  生成指定大小的种群,每个个体都是一个长度为 chromosome_length (本实验为5)的二进制字符串,代表一个取值范围在 0 到 31 之间的整数。函数可以拆分为:

def initialize_population(size):
    return [encode(random.randint(0, 31)) for _ in range(size)]
  • 染色体编码函数 encode(x)
def encode(x):
    return bin(x)[2:].zfill(5)

  将整数 x 编码成一个长度为 5 的二进制字符串。内置的 bin() 函数将整数转换为二进制字符串,然后使用 zfill() 函数填充到长度为 5。

4. 计算适应度
def fitness(chromosome):
    return f(decode(chromosome))

这个函数计算染色体的适应度,即目标函数的取值。它通过先解码染色体,然后将解码后的值代入目标函数 f(x) 中来计算适应度。

5. 选择操作:轮盘赌选择
def selection(population, fitness_values):
    total_fitness = sum(fitness_values)
    # 计算每个个体被选中的概率
    probabilities = [fitness / total_fitness for fitness in fitness_values]
    # print("\t选择概率: {}".format(probabilities))
    selected_population = []
    for _ in range(len(population)):
        selected_individual = random.choices(population, weights=probabilities)[0]
        # print("\t被选个体: {}".format(selected_individual))
        selected_population.append(selected_individual)
    return selected_population

  从轮盘赌选择的机制中可以看到,较优染色体的P值较大,被选择的概率就相对较大。但由于选择过程具有随机性,并不能保证每次选择均选中这些较优的染色体,因此也给予了较差染色体一定的生存空间。

6. 单点交叉操作
def crossover(parent1, parent2):
    crossover_point = random.randint(1, len(parent1) - 1)
    child1 = parent1[:crossover_point] + parent2[crossover_point:]
    child2 = parent2[:crossover_point] + parent1[crossover_point:]
    print("\t\t交叉过程:{} ————> {}\n\t\t\t\t{} ————> {}".format(parent1, child1, parent2, child2))
    return child1, child2

  随机选择一个交叉点,然后将两个父代个体在交叉点处进行交换,生成两个新的子代个体。

7. 变异操作
def mutation(population, mutation_rate):
    mutated_population = []
    for individual in population:
        mutated_individual = ''
        for bit in individual:
            if random.random() < mutation_rate:
                mutated_bit = '0' if bit == '1' else '1'
            else:
                mutated_bit = bit
            mutated_individual += mutated_bit
        if mutated_individual != individual:
            print("\t\t变异过程:{} ————> {}".format(individual, mutated_individual))
        mutated_population.append(mutated_individual)
    return mutated_population

  对于染色体中的每个基因,根据指定的变异率,以一定概率对其进行变异(由 0 变为 1 或由 1 变为 0)。

8. 遗传算法
def genetic_algorithm(population_size, chromosome_length, crossover_rate, mutation_rate, max_iterations):
    population = initialize_population(population_size, chromosome_length)
    best_individual = None
    best_fitness = float('-inf')
    print(f"初始化群体:{population}")
    for iteration in range(max_iterations):
        print(f"第{iteration}代群体:{population}")
        # 评估种群中所有个体的适应度
        fitness_values = evaluate_population(population)
        print(f"\t 适应度: {fitness_values}")
        # 选择操作
        population = selection(population, fitness_values)
        print(f"\t选择操作:{population}")
        # 交叉操作
        for i in range(0, len(population), 2):
            if random.random() < crossover_rate:
                population[i], population[i + 1] = crossover(population[i], population[i + 1])
        print(f"\t交叉操作:{population}")

        # 变异操作
        population = mutation(population, mutation_rate)
        print(f"\t变异操作:{population}")

        # 更新最优个体
        max_fitness = max(fitness_values)
        if max_fitness > best_fitness:
            best_fitness = max_fitness
            best_individual = population[fitness_values.index(max_fitness)]

    return best_individual, best_fitness
    
9. 主程序
if __name__ == '__main__':
    # 设置参数
    population_size = 4  # 群体大小
    chromosome_length = 5  # 由于 x ∈ [0, 31],因此需要 5 位二进制编码
    crossover_rate = 0.9  # (提高)交叉率, 发生交叉的概率较大  𝑃_𝑐=0.8 , 0.9…
    # 哪两个个体配对交叉是随机的,交叉点位置的选取是随机的(单点交叉)
    mutation_rate = 0.01  # (降低)变异率, 变异概率𝑃_𝑚=0.01,0.05 … 交叉点位置的选取是随机的
    max_iterations = 2  # (增加)迭代次数

    # 运行遗传算法
    best_solution, max_fitness = genetic_algorithm(population_size, chromosome_length, crossover_rate, mutation_rate,
                                                   max_iterations)

    # 输出结果
    decoded_best_solution = int(best_solution, 2)
    print("最优解:", decoded_best_solution)
    print("最大适应度:", max_fitness)

在这里插入图片描述

2.3 实验结果与分析

  为了保持遗传算法较好的运行性能,变异概率P_c应该设置在一个合适的范围。变异操作通过改变原有染色体的基因,在提高群体多样性方面具有明显的促进作用如果P过小,算法容易早熟。但是在算法运行的过程中,已找到的较优解可能在变异过程中遭到破坏,如果P的值过大,可能会导致算法目前所处的较好的搜索状态倒退回原来较差的情况。因此,我们应该将种群的变异限制在一定范围内。一般地,P_c可设定在 0.001~0.1之间。

  实验结果显示,在给定的迭代次数内,遗传算法成功找到了函数 f ( x ) = x 2 f(x) = x^2 f(x)=x2 x ∈ [ 0 , 31 ] x \in [0, 31] x[0,31] 范围内的最大值。最终的最优解为 x = 31 x = 31 x=31,对应的最大适应度为 f ( 31 ) = 961 f(31) = 961 f(31)=961。通过动画展示了遗传算法的演化过程,直观地呈现了优化过程中种群的变化和适应度的提升。

2.4 结论与展望

  本文介绍了遗传算法的基本原理和实现过程,并通过实验展示了其在优化问题中的应用。实验结果表明,遗传算法能够有效地搜索解空间,并找到近似最优解。未来,可以进一步研究和优化遗传算法的参数设置、种群初始化和选择策略,以提高算法的性能和收敛速度。

3. 遗传算法的改进

4. 遗传算法的应用

5. 代码整合

import random


# 定义目标函数
def f(x):
    return x ** 2


# 初始化种群
def initialize_population(population_size, chromosome_length):
    return [bin(random.randint(0, 31))[2:].zfill(chromosome_length) for _ in range(population_size)]


# 计算个体的适应度
def evaluate_individual(individual):
    x = int(individual, 2)
    return f(x)


# 评估种群中所有个体的适应度
def evaluate_population(population):
    return [evaluate_individual(individual) for individual in population]


# 选择操作 - 轮盘赌选择算法
"""
从轮盘赌选择的机制中可以看到,较优染色体的P值较大,被选择的概率就相对较大。
但由于选择过程具有随机性,并不能保证每次选择均选中这些较优的染色体,因此也给予了较差染色体一定的生存空间。
"""


def selection(population, fitness_values):
    total_fitness = sum(fitness_values)
    # 计算每个个体被选中的概率
    probabilities = [fitness / total_fitness for fitness in fitness_values]
    # print("\t选择概率: {}".format(probabilities))
    selected_population = []
    for _ in range(len(population)):
        selected_individual = random.choices(population, weights=probabilities)[0]
        # print("\t被选个体: {}".format(selected_individual))
        selected_population.append(selected_individual)
    return selected_population


# 单点交叉操作
def crossover(parent1, parent2):
    crossover_point = random.randint(1, len(parent1) - 1)
    child1 = parent1[:crossover_point] + parent2[crossover_point:]
    child2 = parent2[:crossover_point] + parent1[crossover_point:]
    print("\t\t交叉过程:{} ————> {}\n\t\t\t\t{} ————> {}".format(parent1, child1, parent2, child2))
    return child1, child2


def mutation(population, mutation_rate):
    mutated_population = []
    for individual in population:
        mutated_individual = ''
        for bit in individual:
            if random.random() < mutation_rate:
                mutated_bit = '0' if bit == '1' else '1'
            else:
                mutated_bit = bit
            mutated_individual += mutated_bit
        if mutated_individual != individual:
            print("\t\t变异过程:{} ————> {}".format(individual, mutated_individual))
        mutated_population.append(mutated_individual)
    return mutated_population


# 主程序
def genetic_algorithm(population_size, chromosome_length, crossover_rate, mutation_rate, max_iterations):
    population = initialize_population(population_size, chromosome_length)
    best_individual = None
    best_fitness = float('-inf')
    print(f"初始化群体:{population}")
    for iteration in range(max_iterations):
        print(f"第{iteration}代群体:{population}")
        # 评估种群中所有个体的适应度
        fitness_values = evaluate_population(population)
        print(f"\t 适应度: {fitness_values}")
        # 选择操作
        population = selection(population, fitness_values)
        print(f"\t选择操作:{population}")
        # 交叉操作
        for i in range(0, len(population), 2):
            if random.random() < crossover_rate:
                population[i], population[i + 1] = crossover(population[i], population[i + 1])
        print(f"\t交叉操作:{population}")

        # 变异操作
        population = mutation(population, mutation_rate)
        print(f"\t变异操作:{population}")

        # 更新最优个体
        max_fitness = max(fitness_values)
        if max_fitness > best_fitness:
            best_fitness = max_fitness
            best_individual = population[fitness_values.index(max_fitness)]

    return best_individual, best_fitness


if __name__ == '__main__':
    # 设置参数
    """
    为了保持遗传算法较好的运行性能,变异概率P_c应该设置在一个合适的范围。
    变异操作通过改变原有染色体的基因,在提高群体多样性方面具有明显的促进作用如果P过小,算法容易早熟。
    但是在算法运行的过程中,已找到的较优解可能在变异过程中遭到破坏,如果P的值过大,可能会导致算法目前所处的较好的搜索状态倒退回原来较差的情况。
    因此,我们应该将种群的变异限制在一定范围内。一般地,P_c可设定在 0.001~0.1之间。
    """
    population_size = 4  # 群体大小
    chromosome_length = 5  # 由于 x ∈ [0, 31],因此需要 5 位二进制编码
    crossover_rate = 0.9  # (提高)交叉率, 发生交叉的概率较大  𝑃_𝑐=0.8 , 0.9…
    # 哪两个个体配对交叉是随机的,交叉点位置的选取是随机的(单点交叉)
    mutation_rate = 0.01  # (降低)变异率, 变异概率𝑃_𝑚=0.01,0.05 … 交叉点位置的选取是随机的
    max_iterations = 2  # (增加)迭代次数

    # 运行遗传算法
    best_solution, max_fitness = genetic_algorithm(population_size, chromosome_length, crossover_rate, mutation_rate,
                                                   max_iterations)

    # 输出结果
    decoded_best_solution = int(best_solution, 2)
    print("最优解:", decoded_best_solution)
    print("最大适应度:", max_fitness)

6. 随笔

  遗传算法作为一种启发式优化算法,在解决复杂问题和搜索空间较大的问题时表现出色。本文介绍了遗传算法的基本原理和应用,并通过实验展示了其在优化问题中的效果。希望本文能够对读者理解和应用遗传算法有所帮助。

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

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

相关文章

Django后台项目开发实战二

我们的需求是开发职位管理系统 三个功能&#xff1a; 管理员发布职位候选人能浏览职位用户能投递职位 第二阶段 创建应用 jobs&#xff0c;实现职位数据的建模 python manage.py startapp jobs 然后再 setting .py 注册应用&#xff0c;只需添加应用名称到最后一行 INST…

VTK —— 二、教程六 - 为模型加入3D微件(按下i键隐藏或显示)(附完整源码)

代码效果 本代码编译运行均在如下链接文章生成的库执行成功&#xff0c;若无VTK库则请先参考如下链接编译vtk源码&#xff1a; VTK —— 一、Windows10下编译VTK源码&#xff0c;并用Vs2017代码测试&#xff08;附编译流程、附编译好的库、vtk测试源码&#xff09; 教程描述 本…

探索未来道路:智慧高速系统架构的革命性进步

随着科技的飞速发展&#xff0c;智慧高速系统架构正在成为道路交通领域的一项重要创新。这一系统结合了先进的信息技术和智能化设备&#xff0c;为高速公路提供了全新的管理和服务模式&#xff0c;极大地提升了交通运输效率和安全性。本文将深入探讨智慧高速系统架构的革命性进…

ping命令操作记录

1&#xff0c;ping 主机可查看主机是否在线 2&#xff0c;ping -a参数&#xff0c;解析主机的名称 3&#xff0c;ping -r 跟踪打印路由信息 ping命令的作用&#xff1a;确认目标主机是否存活&#xff0c;确定网络是否畅通 ping的原理&#xff1a;ping发送ICMP&#xff08;互联…

【算法】【贪心算法】【leetcode】870. 优势洗牌

题目地址&#xff1a;https://leetcode.cn/problems/advantage-shuffle/description/ 题目描述&#xff1a; 给定两个长度相等的数组 nums1 和 nums2&#xff0c;nums1 相对于 nums2 的优势可以用满足 nums1[i] > nums2[i] 的索引 i 的数目来描述。 返回 nums1 的任意排列&…

Open CASCADE学习|BRepFill_SectionPlacement

BRepFill_SectionPlacement 是一个与计算机辅助设计&#xff08;CAD&#xff09;相关的术语&#xff0c;通常用于指代一个几何对象或操作&#xff0c;它是Open CASCADE Technology&#xff08;OCCT&#xff09;中的一个类。Open CASCADE Technology是一个开源的CAD内核&#xf…

AnomalyGPT——使用大型视觉语言模型进行工业异常检测的算法解析与应用

1.概述 工业缺陷检测是工业自动化和质量控制中的一个重要环节&#xff0c;其目的是在生产过程中识别和分类产品或组件中的缺陷&#xff0c;以确保最终产品的质量满足既定标准。这项技术的应用可以显著提高生产效率&#xff0c;降低成本&#xff0c;并减少由于缺陷产品导致的潜…

数据挖掘之基于K近邻算法的原油和纳斯达克股票数据预测分析

欢迎大家点赞、收藏、关注、评论啦 &#xff0c;由于篇幅有限&#xff0c;只展示了部分核心代码。 文章目录 一项目简介 二、功能三、系统四. 总结 一项目简介 一、项目背景 在当今日益复杂的金融市场中&#xff0c;准确地预测原油价格和纳斯达克股票市场的走势对于投资者、政…

【docker 】Windows10安装 Docker

安装 Hyper-V Hyper-V 是微软开发的虚拟机&#xff0c;仅适用于 Windows 10。 按键&#xff1a; win键X &#xff0c;选着程序和功能 在查找设置中输入&#xff1a;启用或关闭Windows功能 选中Hyper-V 点击确定 安装 Docker Desktop for Windows Docker Desktop 官方下载…

【漏洞复现】zookeeper AdminServer 未授权访问漏洞

0x01 产品简介 ZooKeeper 是一个集中式服务&#xff0c;用于维护配置信息、命名、提供分布式同步和提供组服务。ZooKeeper的AdminServer是其管理界面的一部分&#xff0c;通常用于监控ZooKeeper集群的状态和执行一些管理操作。AdminServer提供了Web-based的管理和监控功能&…

Springboot+Vue项目-基于Java+MySQL的入校申报审批系统(附源码+演示视频+LW)

大家好&#xff01;我是程序猿老A&#xff0c;感谢您阅读本文&#xff0c;欢迎一键三连哦。 &#x1f49e;当前专栏&#xff1a;Java毕业设计 精彩专栏推荐&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb; &#x1f380; Python毕业设计 &…

从MySQL+MyCAT架构升级为分布式数据库,百丽应用OceanBase 4.2的感受分享

本文来自OceanBase的客户&#xff0c;百丽时尚的使用和测试分享 业务背景 百丽时尚集团&#xff0c;作为国内大型时尚鞋服集团&#xff0c;在中国超过300个城市设有直营门店&#xff0c;数量超过9,000家。集团构建了以消费者需求为核心的垂直一体化业务模式&#xff0c;涵盖了…

Nginx实现端口转发与负载均衡配置

前言&#xff1a;当我们的软件体系结构较为庞大的时候&#xff0c;访问量往往是巨大的&#xff0c;所以我们这里可以使用nginx的均衡负载 一、配置nginx实现端口转发 本地tomcat服务端口为8082 本地nginx端口为8080 目的&#xff1a;将nginx的8080转发到tomcat的8082端口上…

SpringCloud学习笔记(二)Ribbon负载均衡、Nacos注册中心、Nacos与Eureka的区别

文章目录 4 Ribbon负载均衡4.1 负载均衡原理4.2 源码解读4.3 负载均衡策略4.3.1 内置的负载均衡策略4.3.2 自定义负载均衡策略4.3.2.1 方式一&#xff1a;定义IRule4.3.2.2 方式二&#xff1a;配置文件 4.4 饥饿加载 5 Nacos注册中心5.1 认识和安装Nacos5.2 服务注册到Nacos5.3…

Bert基础(二十一)--Bert实战:文本摘要

一、介绍 1.1 文本摘要简介 文本摘要&#xff08;Text Summarization&#xff09;&#xff0c;作为自然语言处理&#xff08;NLP&#xff09;领域的一个分支&#xff0c;其核心目标是从长篇文档中提取关键信息&#xff0c;并生成简短的摘要&#xff0c;以提供对原始内容的高度…

【算法基础实验】图论-最小生成树Prim的延迟实现

最小生成树-Prim的延迟实现 理论基础 树的基本性质 用一条边连接树中的任意两个顶点都会产生一个新的环&#xff1b; 从树中删去一条边将会得到两棵独立的树。 切分定理的定义 定义。图的一种切分是将图的所有顶点分为两个非空且不重叠的两个集合。横切边 是一条连接两个属…

【全网首发】2024五一数学建模ABC题保奖思路(后续会更新)

一定要点击文末的卡片哦&#xff01; 1&#xff09;常见模型分类 机理分析类&#xff1a;来源于实际问题&#xff0c;需要了解一定的物理机理&#xff0c;转化为优化问题。 运筹优化类&#xff1a;旨在找到使某个目标函数取得最大或最小值的最优解,对于机理要求要求不高&…

kube-prometheus部署到 k8s 集群

文章目录 **修改镜像地址****访问配置****修改 Prometheus 的 service****修改 Grafana 的 service****修改 Alertmanager 的 service****安装****Prometheus验证****Alertmanager验证****Grafana验证****卸载****Grafana显示时间问题** 或者配置ingress添加ingress访问grafana…

SQL 基础 | BETWEEN 的常见用法

在SQL中&#xff0c;BETWEEN是一个操作符&#xff0c;用于选取介于两个值之间的数据。 它包含这两个边界值。BETWEEN操作符常用于WHERE子句中&#xff0c;以便选取某个范围内的值。 以下是BETWEEN的一些常见用法&#xff1a; 选取介于两个值之间的值&#xff1a; 使用 BETWEEN来…

数据结构可视化(适合考研党)

废话不多说传送门 还在疑惑平衡二叉树、红黑树、B树、B树怎么插入构建的吗&#xff0c;不要慌张&#xff0c;这个网站会一步一步来演示.&#xff0c;听了咸鱼的课还不够&#xff0c;需要自己动手模拟一下各种数据结构的CRUD&#xff01;&#xff01;
最新文章