news 2026/6/17 4:23:32

AI视觉驱动UI自动化测试:Midscene.js实战指南与跨平台应用

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
AI视觉驱动UI自动化测试:Midscene.js实战指南与跨平台应用

1. 项目概述:当AI视觉成为测试的“眼睛”

最近在跟几个测试团队的朋友聊天,大家普遍头疼一个问题:UI自动化测试的维护成本太高了。一个按钮的>mkdir my-midscene-test cd my-midscene-test npm init -y

接下来,安装Midscene.js的核心包以及我们选择的浏览器驱动。这里我们使用Playwright作为底层驱动,因为它功能强大且与Midscene集成良好。

npm install midscene @midscene/plugin-playwright

同时,安装Playwright浏览器(Chromium, Firefox, WebKit):

npx playwright install

3.2 配置AI模型(关键步骤)Midscene.js的强大依赖于背后的多模态模型。你需要一个API Key来调用模型服务。它支持多种模型,这里我们以获取相对容易的DeepSeek-V3为例(你需要在其官网注册并获取API Key)。你也可以选择GLM、Qwen等国内可访问的模型。

在项目根目录创建一个.env文件,用于安全地存储你的API Key:

DEEPSEEK_API_KEY=your_deepseek_api_key_here

然后,在项目中安装对应的Node.js SDK(以DeepSeek为例):

npm install @deepseek/sdk

3.3 编写第一个自动化脚本现在,让我们创建一个简单的测试脚本first-test.js。这个脚本将打开一个网页,执行一次搜索操作。

// first-test.js import { Midscene } from 'midscene'; import { PlaywrightLauncher } from '@midscene/plugin-playwright'; import { DeepSeek } from '@deepseek/sdk'; // 1. 初始化AI模型客户端 const llmClient = new DeepSeek({ apiKey: process.env.DEEPSEEK_API_KEY, }); // 2. 创建Midscene代理,并指定使用Playwright启动Chrome浏览器 const agent = new Midscene({ launcher: new PlaywrightLauncher({ browserType: 'chromium' }), // 使用Chromium浏览器 llmClient, // 传入配置好的模型客户端 }); async function runTest() { // 3. 启动浏览器并导航到目标页面(例如,百度首页) await agent.launch(); await agent.goto('https://www.baidu.com'); // 4. 使用自然语言驱动自动化 - 核心所在! // 告诉AI:“在搜索框里输入‘Midscene.js自动化测试’” await agent.aiAct('在搜索框里输入“Midscene.js自动化测试”'); // 告诉AI:“点击‘百度一下’按钮” await agent.aiAct('点击“百度一下”按钮'); // 5. 等待一下,看看结果(在实际测试中,这里可以加入断言) await agent.sleep(3000); // 等待3秒 // 6. 可以查询页面内容进行验证 const pageTitle = await agent.aiQuery('当前页面的标题是什么?'); console.log('页面标题可能是:', pageTitle); // 7. 关闭浏览器 await agent.close(); } runTest().catch(console.error);

3.4 运行并观察在终端运行你的脚本:

node first-test.js

如果一切配置正确,你将看到:

  1. 一个Chromium浏览器窗口自动打开,并跳转到百度首页。
  2. 光标会自动移动到搜索框,并输入“Midscene.js自动化测试”。
  3. 接着会自动点击“百度一下”按钮。
  4. 页面跳转到搜索结果页,控制台会输出查询到的页面标题。
  5. 最后浏览器自动关闭。

整个过程,你没有写一行关于inputidbutton标签的代码,仅仅是用两句话描述了你的操作意图。这就是Midscene.js“零代码”精神的体现——将自动化逻辑从繁琐的细节定位中解放出来。

实操心得:模型选择与响应速度第一次运行可能会感觉比传统自动化慢一些,因为需要截图、上传到模型API、等待推理、返回坐标。速度很大程度上取决于你选择的模型和网络延迟。对于追求稳定性和速度的正式测试,建议考虑以下策略:

  1. 使用响应更快的模型:例如,Gemini Flash或GLM-4V-Plus的响应速度通常优于一些更大的模型。
  2. 启用本地缓存:Midscene支持对AI的规划(planning)结果进行缓存。对于稳定不变的界面,首次运行后,后续相同的指令可以直接使用缓存的坐标,速度极快。可以在配置中开启planCache
  3. 优化指令描述:清晰、无歧义的语言指令能帮助模型更快更准地定位。比如“点击左上角蓝色的、写着‘提交’的按钮”就比“点击提交按钮”更精确。

4. 核心API深度解析与实战技巧

掌握了基础用法后,我们来深入拆解Midscene.js提供的核心API,并分享一些在实战中提升稳定性和效率的技巧。Midscene的API设计非常精简,主要围绕aiActaiQueryaiAssert以及一些平台基础操作展开。

4.1aiAct:万能执行器aiAct(instruction: string): Promise<void>这是最常用、最强大的方法。你给它一段自然语言指令,它负责完成从理解、规划到执行的全过程。

// 示例:一个复杂的多步操作,可以一句话搞定 await agent.aiAct('找到商品列表,滑动查看第三行的商品,然后点击它的“加入购物车”按钮');
  • 内部流程aiAct会先对当前界面截图,将截图和你的指令发送给多模态模型。模型会返回一个“规划”,通常是一个动作序列(如:找到某区域 -> 计算坐标 -> 执行点击)。Midscene再根据这个规划驱动底层设备执行。
  • 技巧:对于复杂的操作,拆分成多个aiAct步骤有时比一个长指令更可靠。例如,先aiAct('滑动到页面底部'),再aiAct('点击加载更多按钮')

4.2aiQuery:信息提取器aiQuery<T>(question: string): Promise<T>当你需要从页面上获取信息用于判断或后续逻辑时,使用aiQuery。你可以指定期望的返回类型(string,number,boolean,string[]等)。

// 获取页面上的所有新闻标题(返回字符串数组) const headlines = await agent.aiQuery('string[], 列出当前页面所有新闻标题'); console.log(headies); // 例如:['AI测试新突破', 'Midscene.js发布...'] // 查询当前登录的用户名 const username = await agent.aiQuery('string, 当前登录的用户名显示在哪里?'); console.log('用户是:', username); // 进行一个布尔判断 const isErrorVisible = await agent.aiQuery('boolean, 页面上是否有红色的错误提示信息?'); if (isErrorVisible) { // 执行错误处理 }
  • 技巧:在问题中明确返回类型(如string[],)可以极大地提高模型返回结果的格式准确性,方便后续代码处理。

4.3aiAssert:视觉化断言aiAssert(assertion: string): Promise<void>传统的断言检查属性,而aiAssert检查的是“视觉事实”。它让验证点更贴近用户体验。

// 断言某个关键元素应该被看到 await agent.aiAssert('“支付成功”的提示弹窗应该出现在屏幕中央'); // 断言某个状态不应该出现 await agent.aiAssert('页面上不应出现“网络错误”的提示'); // 复杂的视觉断言 await agent.aiAssert('购物车图标右上角的角标数字应该显示为“3”');

如果断言失败,Midscene会抛出错误,并通常会在生成的测试报告中高亮显示断言失败的截图位置,非常直观。

4.4 基础操作与混合使用除了AI驱动的方法,Midscene也提供了一些基础的、确定性的操作方法,如tap(点击坐标)、type(输入文本)、swipe(滑动)等。最佳实践是将AI驱动与基础操作结合使用,在稳定性和灵活性之间取得平衡。

// 混合模式示例:用AI找到输入框并点击聚焦,然后用精确的type方法输入(避免模型输入错误) await agent.aiAct('点击用户名输入框'); await agent.type('my_username'); // 精确输入 // 用AI找到列表区域,然后用精确的swipe控制滑动距离 await agent.aiAct('找到消息列表区域'); await agent.swipe('up', 500); // 向上滑动500像素

4.5 配置模型与策略Midscene的灵活性也体现在模型配置上。你可以在初始化时传入更详细的配置:

const agent = new Midscene({ launcher: new PlaywrightLauncher({ browserType: 'chromium', headless: false }), // 非无头模式,方便调试 llmClient, modelConfig: { provider: 'deepseek', // 指定提供商 model: 'deepseek-chat-v3', // 指定模型名称 temperature: 0.1, // 降低随机性,使结果更确定 maxTokens: 1000, }, // 启用规划缓存,大幅提升重复执行速度 planCache: { enabled: true, ttl: 3600 * 1000, // 缓存1小时 } });

不同的模型在精度、速度和成本上各有权衡。对于测试任务,通常选择temperature较低(如0.1-0.3)的配置,以减少输出的随机性,保证测试行为的可重复性。

5. 进阶实战:构建一个完整的跨平台自动化测试流程

现在,我们将运用前面所学,设计并实现一个更贴近真实项目的测试场景:测试一个跨平台(Web和移动端)的Todo应用的核心流程。我们将覆盖创建任务、标记完成、筛选和删除任务等操作,并展示如何组织测试代码。

5.1 测试场景与架构设计假设我们有一个简单的Todo应用,其Web版地址是https://demo.todoapp.com,移动端有对应的App。我们的测试目标是:

  1. Web端测试:打开应用,添加两个新任务,将其中一个标记为完成,然后筛选查看未完成的任务,最后删除一个任务。
  2. 移动端测试:在Android模拟器上打开App,执行类似的核心流程验证。

我们将测试逻辑抽象成与平台无关的“页面对象”或“业务流程”,然后针对不同平台注入不同的Midscene驱动实例。

5.2 实现平台无关的业务流首先,我们创建一个业务逻辑文件todoWorkflow.js

// todoWorkflow.js export class TodoWorkflow { constructor(agent) { this.agent = agent; // 接收传入的Midscene代理实例 } async addTask(taskName) { await this.agent.aiAct(`在输入框里添加新任务,内容为“${taskName}”`); await this.agent.aiAct('点击“添加”或回车确认'); console.log(`已添加任务: ${taskName}`); } async markTaskComplete(taskName) { await this.agent.aiAct(`找到任务“${taskName}”,点击它左侧的复选框或完成按钮`); console.log(`已标记任务为完成: ${taskName}`); } async filterTasks(filter) { // filter: 'all', 'active', 'completed' await this.agent.aiAct(`点击筛选器,切换到“${filter}”视图`); console.log(`已筛选查看: ${filter} 任务`); } async deleteTask(taskName) { await this.agent.aiAct(`找到任务“${taskName}”,将鼠标悬停或长按它`); await this.agent.aiAct('点击出现的“删除”或垃圾桶图标'); console.log(`已删除任务: ${taskName}`); } async getTaskList() { const list = await this.agent.aiQuery('string[], 列出当前可见的所有任务文本'); return list; } }

5.3 Web端测试脚本接下来,创建Web端的测试脚本test.web.js

// test.web.js import { Midscene } from 'midscene'; import { PlaywrightLauncher } from '@midscene/plugin-playwright'; import { DeepSeek } from '@deepseek/sdk'; import { TodoWorkflow } from './todoWorkflow.js'; import dotenv from 'dotenv'; dotenv.config(); async function runWebTest() { const llmClient = new DeepSeek({ apiKey: process.env.DEEPSEEK_API_KEY }); const agent = new Midscene({ launcher: new PlaywrightLauncher({ browserType: 'chromium', headless: false }), llmClient, }); const todoApp = new TodoWorkflow(agent); try { await agent.launch(); await agent.goto('https://demo.todoapp.com'); // 1. 添加任务 await todoApp.addTask('学习Midscene.js'); await todoApp.addTask('编写自动化测试用例'); await agent.sleep(1000); // 短暂等待 // 2. 标记一个任务为完成 await todoApp.markTaskComplete('学习Midscene.js'); // 3. 验证列表 let tasks = await todoApp.getTaskList(); console.log('当前所有任务:', tasks); // 这里可以加入更正式的断言,例如使用Node的assert库 // assert(tasks.includes('编写自动化测试用例')); // 4. 筛选查看未完成的任务 await todoApp.filterTasks('active'); tasks = await todoApp.getTaskList(); console.log('未完成任务:', tasks); // assert(tasks.length === 1 && tasks[0] === '编写自动化测试用例'); // 5. 删除一个任务 await todoApp.filterTasks('all'); // 切回全部视图 await todoApp.deleteTask('编写自动化测试用例'); // 6. 最终验证 tasks = await todoApp.getTaskList(); console.log('最终任务列表:', tasks); // assert(tasks.length === 1 && tasks[0] === '学习Midscene.js'); console.log('Web端测试流程执行完毕!'); } catch (error) { console.error('测试执行失败:', error); // 通常在这里可以保存失败的截图,Midscene报告会自动生成 } finally { await agent.close(); } } runWebTest();

5.4 移动端(Android)测试脚本移动端测试需要连接设备或模拟器。我们以Android为例,使用@midscene/plugin-android插件。 首先安装插件:

npm install @midscene/plugin-android

确保你的Android设备已通过USB连接并启用调试模式,或者模拟器正在运行。

创建测试脚本test.android.js

// test.android.js import { Midscene } from 'midscene'; import { AndroidLauncher } from '@midscene/plugin-android'; import { DeepSeek } from '@deepseek/sdk'; import { TodoWorkflow } from './todoWorkflow.js'; import dotenv from 'dotenv'; dotenv.config(); async function runAndroidTest() { const llmClient = new DeepSeek({ apiKey: process.env.DEEPSEEK_API_KEY }); // 假设Todo App的包名是 com.demo.todoapp const agent = new Midscene({ launcher: new AndroidLauncher({ appPackage: 'com.demo.todoapp' }), llmClient, }); const todoApp = new TodoWorkflow(agent); try { // 启动Android应用 await agent.launch(); // 接下来的业务流程与Web端完全一致! await todoApp.addTask('移动端任务一'); await todoApp.addTask('移动端任务二'); await agent.sleep(1000); await todoApp.markTaskComplete('移动端任务一'); await todoApp.filterTasks('active'); // ... 后续断言和验证 console.log('Android端测试流程执行完毕!'); } catch (error) { console.error('Android测试失败:', error); } finally { await agent.close(); } } runAndroidTest();

可以看到,除了初始化Midscene时使用的Launcher不同(PlaywrightLaunchervsAndroidLauncher),核心的业务流程代码TodoWorkflow完全复用的。这充分体现了Midscene.js“一套API,全平台通用”的巨大优势。

5.5 测试报告与可视化Midscene.js在运行时会自动生成丰富的可视化报告。默认情况下,每次aiActaiQueryaiAssert的调用,都会记录当时的屏幕截图、AI的规划结果以及执行结果。测试结束后,会在项目目录下生成一个HTML报告文件。 你可以在初始化代理时配置报告路径和详细程度:

const agent = new Midscene({ launcher: ..., llmClient, report: { outputDir: './midscene-reports', detailLevel: 'high', // 'low', 'medium', 'high' } });

打开报告HTML文件,你可以像看视频一样逐帧回放整个自动化过程,清晰地看到AI每一步“看”到了什么,“想”做什么,以及最终执行的效果。这对于调试失败的测试用例、理解AI的决策过程具有无可替代的价值。

6. 避坑指南与性能优化实战

在实际项目中大规模应用Midscene.js,你会遇到一些特有的挑战。下面是我在多个项目中总结出的常见问题与优化策略。

6.1 稳定性提升:让AI“看”得更准AI视觉模型并非100%准确,以下策略可以显著提升定位成功率:

  1. 指令描述具体化、唯一化
    • 点击按钮
    • 点击页面顶部导航栏中蓝色的、写着“提交订单”的按钮
    • 技巧:结合位置(顶部/底部/左侧)、颜色、文字、邻近元素(“在‘用户名’输入框下面的那个按钮”)进行描述。
  2. 分步操作,降低复杂度
    • 对于复杂操作,不要试图用一句aiAct完成。拆分成多个步骤,每一步让AI只做一件简单的事。例如,先aiAct('滚动到页面底部'),再aiAct('点击“加载更多”')
  3. 结合确定性等待与重试
    • 在关键操作后,使用agent.sleep()等待界面稳定。
    • 对于可能因网络或渲染导致短暂不可见的元素,可以实现一个简单的重试逻辑。
    async function clickWithRetry(description, maxRetries = 3) { for (let i = 0; i < maxRetries; i++) { try { await agent.aiAct(description); return; // 成功则退出 } catch (error) { console.log(`第${i+1}次尝试点击【${description}】失败,等待后重试`); await agent.sleep(1000); } } throw new Error(`多次重试后仍无法点击: ${description}`); } await clickWithRetry('点击保存按钮');
  4. 使用区域限定(ROI)
    • 如果知道目标元素大概在屏幕的某个区域,可以先用aiAct或基础操作将视图调整到该区域附近,或者使用agent.screenshot({ clip: { x, y, width, height } })只截取部分区域送给AI分析,减少干扰,提高精度和速度。

6.2 执行速度优化:从“能用”到“高效”视觉AI推理需要时间,以下是提速关键:

  1. 启用并合理配置规划缓存
    • 这是最重要的优化手段。对于稳定不变的界面(如登录页、导航栏),首次运行后的操作规划会被缓存。后续运行相同指令时,直接使用缓存坐标,速度是毫秒级。
    const agent = new Midscene({ // ... 其他配置 planCache: { enabled: true, ttl: 24 * 3600 * 1000, // 缓存24小时 strategy: 'aggressive', // 积极缓存 } });
  2. 选择高速模型
    • 在精度可接受的前提下,优先选择响应速度快的模型,如gemini-1.5-flashqwen2.5-vl-7b-instruct(如果本地部署)。
  3. 减少不必要的截图和AI调用
    • 对于连续多个肯定能由AI一步完成的操作,尽量合并到一个aiAct指令中。
    • 对于确定性的、位置不变的操作(如已知坐标的点击),直接使用agent.tap(x, y)
  4. 并行执行
    • 如果测试套件中有大量独立的测试用例,可以考虑使用Node.js的异步机制并行启动多个Midscene实例(注意机器资源),但需确保模型API的调用频率限制。

6.3 成本控制使用云端大模型API会产生费用。在测试中控制成本:

  1. 充分利用缓存:规划缓存不仅能提速,还能避免重复的、收费的API调用。
  2. 本地部署开源模型:对于对数据隐私和成本敏感的项目,可以考虑在本地GPU服务器上部署开源的视觉大模型(如Qwen-VL、LLaVA),并通过Midscene的配置指向本地API端点。初期投入硬件成本,但长期使用成本极低。
  3. 精细化指令:清晰、简短的指令消耗的Token更少。
  4. 区分测试环境:在开发调试阶段,可以使用速度较慢但免费的限额API或小模型;在CI/CD流水线中,再使用更稳定、更快的付费模型。

6.4 集成到现有测试框架Midscene.js可以轻松集成到Jest、Mocha、Playwright Test等主流测试框架中,让你在同一个测试项目中混合使用传统断言和视觉AI断言。 例如,与Jest集成:

// todo.spec.js import { Midscene } from 'midscene'; import { PlaywrightLauncher } from '@midscene/plugin-playwright'; describe('Todo App Visual Tests', () => { let agent; beforeAll(async () => { agent = new Midscene({ launcher: new PlaywrightLauncher({ headless: true }) }); await agent.launch(); await agent.goto('https://demo.todoapp.com'); }); afterAll(async () => { await agent.close(); }); test('should add a new task visually', async () => { await agent.aiAct('在输入框输入“Jest集成测试”并添加'); // 使用Jest的expect进行混合断言 const tasks = await agent.aiQuery('string[], 页面上的任务列表'); expect(tasks).toContain('Jest集成测试'); // 使用视觉断言 await agent.aiAssert('“Jest集成测试”这个任务项应该显示在列表中'); }); });

这样,你就可以在关键的、易变的UI环节使用Midscene,在稳定的数据验证环节使用传统断言,形成优势互补。

7. 常见问题排查与解决方案实录

即使做了充分优化,在实际运行中仍可能遇到问题。下面是一个快速排查清单,基于我遇到的实际案例整理。

问题现象可能原因排查步骤与解决方案
aiAct执行失败,报错“无法定位元素”1. 指令描述模糊或有歧义。
2. 界面尚未加载完成。
3. 目标元素在当前视口不可见。
4. 模型能力限制,无法理解复杂指令。
1.检查指令:将指令描述得更具体、唯一。打开测试报告,查看AI“看到”的截图和它的“规划”,确认它理解是否正确。
2.添加等待:在操作前加入await agent.sleep()或等待某个视觉标志出现await agent.aiAssert('“加载中” spinner 消失')
3.滚动到可见区域:先执行await agent.aiAct('滚动屏幕直到看到[目标元素附近特征]')
4.简化或拆分指令:将一个复杂指令拆成多个简单步骤。
测试运行速度非常慢1. 网络延迟高(调用云端API)。
2. 未启用规划缓存。
3. 每一步操作后都进行了全屏截图和高精度模型调用。
1.启用缓存:确认planCache.enabledtrue
2.检查网络:考虑更换API地域或使用本地模型。
3.优化操作流:合并连续操作到一个指令中。对于非关键步骤,使用确定性操作(如tap)代替aiAct
4.降低截图分辨率:在初始化配置中尝试设置screenshot: { quality: 80 }或指定clip区域。
相同指令在不同时间运行结果不一致1. 界面存在动态内容(广告、时间、随机推荐)。
2. 模型输出的随机性(temperature设置过高)。
3. 屏幕分辨率或缩放比例发生变化。
1.稳定测试环境:在测试前关闭或屏蔽动态内容。使用固定的测试数据。
2.降低模型随机性:设置modelConfig: { temperature: 0.1 }
3.固定设备/视口尺寸:在launcher配置中固定浏览器窗口或移动设备屏幕分辨率。
4.采用相对描述:避免使用“第一个”、“第二个”这种依赖于动态排序的描述,改用更稳定的特征,如“标题包含‘待办’的卡片”。
移动端测试无法连接设备1. Android设备未开启USB调试。
2. 设备未授权此电脑进行调试。
3. ADB环境变量未正确设置或存在多个ADB冲突。
4. 模拟器未启动或端口被占用。
1.检查设备:在设备上确认“开发者选项”和“USB调试”已开启。连接后查看设备是否弹出授权对话框并点击允许。
2.检查ADB:在终端运行adb devices,确认设备已列出。如果未列出,尝试adb kill-server && adb start-server
3.指定设备:在AndroidLauncher配置中传入deviceId参数,明确指定使用哪个设备。
生成的报告中没有截图或信息不全1. 报告输出目录配置错误或没有写入权限。
2.detailLevel设置过低。
3. 测试过程因异常提前终止。
1.检查配置:确认report.outputDir路径存在且可写。
2.提高详细度:设置detailLevel: 'high'
3.添加异常处理:在测试脚本的catch块中,确保agent.close()被调用,以便正常结束并生成报告。
AI对<canvas>或游戏界面操作不准确1. 纯画布渲染的内容没有传统的UI元素结构,模型难以理解其内部组件。
2. 动态游戏画面变化太快。
1.混合模式:对于已知固定位置的画布内按钮,使用agent.tap(绝对坐标)进行点击。
2.特征描述:用画布内独特的颜色、形状、纹理作为描述。例如:点击画布中央那个红色的圆形按钮
3.降低期望:目前对于高度动态、非标准UI的游戏界面,视觉AI的可靠性仍低于传统基于坐标的脚本。

最后,一个最重要的心得是:将Midscene.js视为一个强大的“实习生”或“助手”,而不是全知全能的“机器人”。你需要用清晰、明确的指令引导它,为它创造稳定、一致的测试环境,并在关键节点设置检查点(断言)。当你能娴熟地结合其视觉理解能力和你的业务逻辑时,它将成为你应对复杂、多变UI自动化测试挑战的一把利器。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/17 4:07:19

定论已定:2026起,工作流掌控企业数字化八成格局

2026年5月&#xff0c;中国信息通信研究院正式发布《中国低代码平台发展白皮书&#xff08;2026年中版&#xff09;》&#xff0c;行业最重磅预判落地&#xff1a;2026年后&#xff0c;标准化自定义低代码工作流&#xff0c;将主导80%企业数字化场景落地。 这份报告直接击碎行业…

作者头像 李华
网站建设 2026/6/17 4:02:01

大麦网自动抢票神器:告别手速焦虑的终极解决方案

大麦网自动抢票神器&#xff1a;告别手速焦虑的终极解决方案 【免费下载链接】Autoticket 大麦网自动抢票工具 项目地址: https://gitcode.com/gh_mirrors/au/Autoticket 还在为抢不到演唱会门票而烦恼吗&#xff1f;每次开票瞬间眼睁睁看着心仪的座位被秒光&#xff1f…

作者头像 李华
网站建设 2026/6/17 3:55:43

chap 8排序

chap 8排序 动态演示排序网站&#xff1a;Comparison Sorting Visualization 8.1 插入排序 算法思想&#xff1a; 每次将一个待排序的记录插入到前面已经排好序的子序列中&#xff0c;直到所有序列插入完成。 ①直接插入排序 代码&#xff1a; //直接插入排序 void Inse…

作者头像 李华
网站建设 2026/6/17 3:42:52

MAA明日方舟自动化助手:游戏效率革命的终极方案

MAA明日方舟自动化助手&#xff1a;游戏效率革命的终极方案 【免费下载链接】MaaAssistantArknights 《明日方舟》小助手&#xff0c;全日常一键长草&#xff01;| A one-click tool for the daily tasks of Arknights, supporting all clients. 项目地址: https://gitcode.c…

作者头像 李华