HarmonyOS Next 中的状态管理
在声明式UI编程框架中,UI是程序状态的运行结果,用户构建了一个UI模型,其中应用的运行时的状态是参数。当参数改变时,UI作为返回结果,也将进行对应的改变。这些运行时的状态变化所带来的UI的重新渲染,在ArkUI中统称为状态管理机制。
一、装饰器总览
ArkUI提供了多种装饰器,根据状态变量的影响范围,将所有的装饰器可以大致分为:
- 管理组件拥有状态的装饰器:组件级别的状态管理,可以观察组件内变化,和不同组件层级的变化,但需要同一个页面内。
- 管理应用拥有状态的装饰器:应用级别的状态管理,可以观察不同页面,甚至不同UIAbility的状态变化,是应用内全局的状态管理。

上图中,Components部分的装饰器为组件级别的状态管理,Application部分为应用的状态管理。
管理组件拥有的状态,即图中Components级别的状态管理:
@State:@State装饰的变量拥有其所属组件的状态,可以作为其子组件单向和双向同步的数据源。当其数值改变时,会引起相关组件的渲染刷新。@Prop:@Prop装饰的变量可以和父组件建立单向同步关系,@Prop装饰的变量是可变的,但修改不会同步回父组件。@Link:@Link装饰的变量和父组件构建双向同步关系的状态变量,父组件会接受来自@Link装饰的变量的修改的同步,父组件的更新也会同步给@Link装饰的变量。@Provide/@Consume:@Provide/@Consume装饰的变量用于跨组件层级(多层组件)同步状态变量,可以不需要通过参数命名机制传递,通过alias(别名)或者属性名绑定。@Observed:@Observed装饰class,需要观察多层嵌套场景的class需要被@Observed装饰。单独使用@Observed没有任何作用,需要和@ObjectLink、@Prop连用。@ObjectLink:@ObjectLink装饰的变量接收@Observed装饰的class的实例,应用于观察多层嵌套场景,和父组件的数据源构建双向同步。
管理应用拥有的状态,即图中Application级别的状态管理:
LocalStorage:页面级UI状态存储,通常用于UIAbility内、页面间的状态共享。AppStorage:特殊的单例LocalStorage对象,由UI框架在应用程序启动时创建,为应用程序UI状态属性提供中央存储。PersistentStorage:持久化存储UI状态,通常和AppStorage配合使用,选择AppStorage存储的数据写入磁盘,以确保这些属性在应用程序重新启动时的值与应用程序关闭时的值相同。Environment:应用程序运行的设备的环境参数,环境参数会同步到AppStorage中,可以和AppStorage搭配使用。
其他状态管理功能
@Watch用于监听状态变量的变化。$$运算符:给内置组件提供TS变量的引用,使得TS变量和内置组件的内部状态保持同步。
二、管理组件拥有的状态
1、@State装饰器:组件内状态
@State装饰的变量,或称为状态变量,一旦变量拥有了状态属性,就和自定义组件的渲染绑定起来。当状态改变时,UI会发生对应的渲染改变。
@State装饰的变量拥有以下特点:
- @State装饰的变量与子组件中的@Prop装饰变量之间建立单向数据同步,与@Link、@ObjectLink装饰变量之间建立双向数据同步。
- @State装饰的变量生命周期与其所属自定义组件的生命周期相同。
- 支持多种数据类型:允许 Object、class、string、number、boolean、enum、Date类型,以及这些类型的数组。
- 内部私有:标记为 @State 的属性是私有变量,只能在组件内访问。
- 支持多个实例:组件不同实例的内部状态数据独立。
- 需要本地初始化:必须为所有 @State 变量分配初始值,将变量保持未初始化可能导致框架行为未定义,初始值需要是有意义的值,比如设置
class类型的值为null就是无意义的,会导致编译报错。 - 创建自定义组件时支持通过状态变量名设置初始值:在创建组件实例时,可以通过变量名显式指定 @State 状态属性的初始值。
装饰class对象类型的变量
当装饰的数据类型为class或者Object时,可以观察到自身的赋值的变化,和其属性赋值的变化,即Object.keys(observedObject)返回的所有属性
创建一个Model对象
class Model {public value: string;constructor(value: string) {this.value = value;}
}
在父组件中初始化@State装饰对象,父组件初始化将会覆盖本地初始化。
@Entry
@Component
struct EntryComponent {build() {Column() {// 此处指定的参数都将在初始渲染时覆盖本地定义的默认值,并不是所有的参数都需要从父组件初始化MyComponent({ count: 1, increaseBy: 2 }).width(300)MyComponent({ title: new Model('Hello World 2'), count: 7 })}}
}
在本地初始化@State装饰对象,@State变量更新会触发组件UI更新
@Component
struct MyComponent {@State title: Model = new Model('Hello World');@State count: number = 0;private increaseBy: number = 1;build() {Column() {Text(`${this.title.value}`).margin(10)Button(`Click to change title`).onClick(() => {// @State变量的更新将触发上面的Text组件内容更新this.title.value = this.title.value === 'Hello ArkUI' ? 'Hello World' : 'Hello ArkUI';}).width(300).margin(10)Button(`Click to increase count = ${this.count}`).onClick(() => {// @State变量的更新将触发该Button组件的内容更新this.count += this.increaseBy;}).width(300).margin(10)}}
}

2、@Prop装饰器:父子单向同步
@Prop装饰的变量可以和父组件建立单向的同步关系。@Prop装饰的变量是可变的,但是变化不会同步回其父组件。
@Prop装饰的变量拥有以下特点:
- 支持简单数据类型:仅支持
number、string、boolean、Object、class、enum类型; - 内部私有:标记为
@Prop的属性是私有变量,只能在组件内访问。 - 支持多个实例:组件不同实例的内部状态数据独立。
- @Prop装饰器不能在@Entry装饰的自定义组件中使用。
@Component
struct CountDownComponent {@Prop count: number = 0;costOfOneAttempt: number = 1;build() {Column() {if (this.count > 0) {Text(`You have ${this.count} Nuggets left`)} else {Text('Game over!')}// @Prop装饰的变量不会同步给父组件Button(`Try again`).onClick(() => {this.count -= this.costOfOneAttempt;})}}
}@Entry
@Component
struct ParentComponent {@State countDownStartValue: number = 10;build() {Column() {Text(`Grant ${this.countDownStartValue} nuggets to play.`)// 父组件的数据源的修改会同步给子组件Button(`+1 - Nuggets in New Game`).onClick(() => {this.countDownStartValue += 1;})// 父组件的修改会同步给子组件Button(`-1 - Nuggets in New Game`).onClick(() => {this.countDownStartValue -= 1;})CountDownComponent({ count: this.countDownStartValue, costOfOneAttempt: 2 })}}
}
3、@Link装饰器:父子双向同步
子组件中被@Link装饰的变量与其父组件中对应的数据源建立双向数据绑定。@Link装饰的变量与其父组件中的数据源共享相同的值。
@Link装饰的变量拥有以下特点:
- Object、class、string、number、boolean、enum类型,以及这些类型的数组。支持Date类型。
- 内部私有:标记为
@Link的属性是私有变量,只能在组件内访问。 - 支持多个实例:组件不同实例的内部状态数据独立。
- 不支持内部初始化:在创建组件的新实例时,必须将值传递给
@Link修饰的变量进行初始化,不支持在组件内部进行初始化。
class GreenButtonState {width: number = 0;constructor(width: number) {this.width = width;}
}@Component
struct GreenButton {@Link greenButtonState: GreenButtonState;build() {Button('Green Button').width(this.greenButtonState.width).height(40).backgroundColor('#64bb5c').fontColor('#FFFFFF,90%').onClick(() => {if (this.greenButtonState.width < 700) {// 更新class的属性,变化可以被观察到同步回父组件this.greenButtonState.width += 60;} else {// 更新class,变化可以被观察到同步回父组件this.greenButtonState = new GreenButtonState(180);}})}
}@Component
struct YellowButton {@Link yellowButtonState: number;build() {Button('Yellow Button').width(this.yellowButtonState).height(40).backgroundColor('#f7ce00').fontColor('#FFFFFF,90%').onClick(() => {// 子组件的简单类型可以同步回父组件this.yellowButtonState += 40.0;})}
}@Entry
@Component
struct ShufflingContainer {@State greenButtonState: GreenButtonState = new GreenButtonState(180);@State yellowButtonProp: number = 180;build() {Column() {Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center }) {// 简单类型从父组件@State向子组件@Link数据同步Button('Parent View: Set yellowButton').width(312).height(40).margin(12).fontColor('#FFFFFF,90%').onClick(() => {this.yellowButtonProp = (this.yellowButtonProp < 700) ? this.yellowButtonProp + 40 : 100;})// class类型从父组件@State向子组件@Link数据同步Button('Parent View: Set GreenButton').width(312).height(40).margin(12).fontColor('#FFFFFF,90%').onClick(() => {this.greenButtonState.width = (this.greenButtonState.width < 700) ? this.greenButtonState.width + 100 : 100;})// class类型初始化@LinkGreenButton({ greenButtonState: $greenButtonState }).margin(12)// 简单类型初始化@LinkYellowButton({ yellowButtonState: $yellowButtonProp }).margin(12)}}}
}
1.点击子组件GreenButton和YellowButton中的Button,子组件会发生相应变化,将变化同步给父组件。因为@Link是双向同步,会将变化同步给@State。
2.当点击父组件ShufflingContainer中的Button时,@State变化,也会同步给@Link,子组件也会发生对应的刷新。
三、管理应用拥有的状态
1、LocalStorage:页面级UI状态存储
LocalStorage是页面级的UI状态存储,通过@Entry装饰器接收的参数可以在页面内共享同一个LocalStorage实例。LocalStorage支持UIAbility实例内多个页面间状态共享。
LocalStorage是ArkTS为构建页面级别状态变量提供存储的内存内“数据库”。
- 应用程序可以创建多个LocalStorage实例,LocalStorage实例可以在页面内共享,也可以通过GetShared接口,实现跨页面、UIAbility实例内共享。
- 组件树的根节点,即被@Entry装饰的@Component,可以被分配一个LocalStorage实例,此组件的所有子组件实例将自动获得对该LocalStorage实例的访问权限。
- 被@Component装饰的组件最多可以访问一个LocalStorage实例和AppStorage,未被@Entry装饰的组件不可被独立分配LocalStorage实例,只能接受父组件通过@Entry传递来的LocalStorage实例。一个LocalStorage实例在组件树上可以被分配给多个组件。
- LocalStorage中的所有属性都是可变的。
LocalStorage根据与@Component装饰的组件的同步类型不同,提供了两个装饰器:
- @LocalStorageProp:@LocalStorageProp装饰的变量和与LocalStorage中给定属性建立单向同步关系。
- @LocalStorageLink:@LocalStorageLink装饰的变量和在@Component中创建与LocalStorage中给定属性建立双向同步关系。
2、AppStorage:应用全局的UI状态存储
AppStorage是应用全局的UI状态存储,是和应用的进程绑定的,由UI框架在应用程序启动时创建,为应用程序UI状态属性提供中央存储。
和AppStorage不同的是,LocalStorage是页面级的,通常应用于页面内的数据共享。而AppStorage是应用级的全局状态共享,还相当于整个应用的“中枢”,持久化数据PersistentStorage和环境变量Environment都是通过AppStorage中转,才可以和UI交互。
@StorageProp
- 单向同步:从AppStorage的对应属性到组件的状态变量。
- Object、 class、string、number、boolean、enum类型,以及这些类型的数组。
- 组件本地的修改是允许的,但是AppStorage中给定的属性一旦发生变化,将覆盖本地的修改。
- @StorageProp不支持从父节点初始化,只能AppStorage中key对应的属性初始化,如果没有对应key的话,将使用本地默认值初始化。
@StorageLink
@StorageLink(key) 装饰的变量是组件内部的状态数据,当这些状态数据被修改时,将会调用所在组件的 build() 方法进行UI刷新。组件通过使用 @StorageLink(key) 装饰的状态变量与 AppStorage 建立双向数据绑定。
- 支持多种数据类型:支持的数据类型和
@State一致且支持object。 - 需要本地初始化:必须为所有
@StorageLink变量分配初始值。 - 数据状态全局化:使用
@StorageLink修饰的数据变化后全局都会改变。 - 数据持久化:通过搭配
PersistentStorage接口实现数据持久化。
@Entry @Component struct ComponentTest {@StorageLink('time') time: string = "1648643734154";// 使用StorageLink标记并初始化build() {Column({space: 10}) {Text(`父组件【${this.time}】`) // 使用time值.fontSize(20).backgroundColor(Color.Pink)Button('更新时间').onClick(() => {this.time = new Date().getTime().toString();// 更改time的值})}.width('100%').height('100%').padding(10)}
}
四、其他状态管理
1、@Watch装饰器:状态变量更改通知
@Watch 用来监听状态变量的变化,当它修饰的状态变量发生变更时,回调相应的方式,
- 当观察到状态变量的变化的时候,对应的@Watch的回调方法将被触发;
- @Watch方法在自定义组件的属性变更之后同步执行;
- 如果在@Watch的方法里改变了其他的状态变量,也会引起状态变更和@Watch的执行;
- 在第一次初始化的时候,@Watch装饰的方法不会被调用,即认为初始化不是状态变量的改变。只有在后续状态改变时,才会调用@Watch回调方法。
- 为了避免循环的产生,建议不要在@Watch的回调方法里修改当前装饰的状态变量;
- 不建议在@Watch函数中调用async await,异步行为可能会导致重新渲染速度的性能问题。
//给状态变量 `count` 增加一个 `@Watch` 装饰器,通过 `@Watch` 注册一个回调方法 `function_name`
@State @Watch("function_name") count : number = 0;//当状态变量 `count` 被改变时, 触发 `function_name` 回调。
function_name(propName: string): void {}
2、@Watch和自定义组件更新
@Component
struct TotalView {@Prop @Watch('onCountUpdated') count: number = 0;@State total: number = 0;// @Watch 回调onCountUpdated(propName: string): void {this.total += this.count;}build() {Text(`Total: ${this.total}`)}
}@Entry
@Component
struct CountModifier {@State count: number = 0;build() {Column() {Button('add to basket').onClick(() => {this.count++})TotalView({ count: this.count })}}
}
3、$$语法:内置组件双向同步
$$运算符为系统内置组件提供TS变量的引用,使得TS变量和系统内置组件的内部状态保持同步。
以TextInput方法的text参数为例:
@Entry
@Component
struct TextInputExample {@State text: string = ''controller: TextInputController = new TextInputController()build() {Column({ space: 20 }) {Text(this.text)TextInput({ text: $$this.text, placeholder: 'input your word...', controller: this.controller }).placeholderColor(Color.Grey).placeholderFont({ size: 14, weight: 400 }).caretColor(Color.Blue).width(300)}.width('100%').height('100%').justifyContent(FlexAlign.Center)}
}
相关文章:
HarmonyOS Next 中的状态管理
在声明式UI编程框架中,UI是程序状态的运行结果,用户构建了一个UI模型,其中应用的运行时的状态是参数。当参数改变时,UI作为返回结果,也将进行对应的改变。这些运行时的状态变化所带来的UI的重新渲染,在ArkU…...
基于qiime2的16S数据分析全流程:从导入数据到下游分析一条龙
目录 创建metadata 把数据导入qiime2 去除引物序列 双端合并 (dada2不需要) 质控 (dada2不需要) 使用deblur获得特征序列 使用dada2生成代表序列与特征表 物种鉴定 可视化物种鉴定结果 构建进化树(ITS一般不构建进化树…...
【软件测试开发】:软件测试常用函数1.0(C++)
1. 元素的定位 web⾃动化测试的操作核⼼是能够找到⻚⾯对应的元素,然后才能对元素进⾏具体的操作。 常⻅的元素定位⽅式⾮常多,如id,classname,tagname,xpath,cssSelector 常⽤的主要由cssSelector和xpath…...
vue2项目修改浏览器显示的网页图标
1.准备一个新的图标文件,通常是. ico格式,也可以是. Png、. Svg等格式 2.将新的图标文件(例如:faviconAt.png)放入项目的public文件夹中。如下图 public文件夹中的所有文件都会在构建时原样复制到最终的输出目录(通常是dist) 3. 修改vue项目…...
开源、创新与人才发展:机器人产业的战略布局与稚晖君成功案例解析
目录 引言 一、开源:机器人产业的战略布局 促进技术进步和生态建设 吸引人才和合作伙伴 建立标准和网络效应 降低研发风险与成本 二、稚晖君:华为"天才少年计划"的成功典范 深厚的技术积累与动手能力 强烈的探索和创新意识 持续公开…...
线程相关作业
1.创建两个线程,分支线程1拷贝文件的前一部分,分支线程2拷贝文件的后一部分 #include "head.h"#define BUFFER_SIZE 1024// 线程参数结构体,包含文件名和文件偏移量 typedef struct {FILE *src_file;FILE *dest_file;long start_o…...
通义万相2.1开源版本地化部署攻略,生成视频再填利器
2025 年 2 月 25 日晚上 11:00 通义万相 2.1 开源发布,前两周太忙没空搞它,这个周末,也来本地化部署一个,体验生成效果如何,总的来说,它在国内文生视频、图生视频的行列处于领先位置,…...
【模拟CMOS集成电路设计】带隙基准(Bandgap)设计与仿真(基于运放的电流模BGR)
【模拟CMOS集成电路设计】带隙基准(Bandgap)设计与仿真 前言工程文件&部分参数计算过程,私聊~ 一、 设计指标指标分析: 二、 电路分析三、 仿真3.1仿真电路图3.2仿真结果(1)运放增益(2)基准温度系数仿真(3)瞬态启动仿真(4)静态…...
如何选择国产串口屏?
目录 1、迪文 2、淘晶驰 3、广州大彩 4、金玺智控 5、欣瑞达 6、富莱新 7、冠显 8、有彩 串口屏,顾名思义,就是通过串口通信接口(如RS232、RS485、TTL UART等)与主控设备进行通信的显示屏。其核心功能是显示信息和接收输入…...
Solana中的程序派生地址(PDAs):是什么,为什么,以及如何?
程序派生地址 (PDA) 在 Solana 中的应用:什么、为什么和如何? 在学习 Solana 时,你会经常听到关于 程序派生地址 (PDAs) 的讨论。它们就像这样 —— 强大、多功能,而且最重要的是,稍微被误解。如果你是一个开发者&…...
利用FatJar彻底解决Jar包冲突(一)
利用FatJar彻底解决Jar包冲突 序FatJar的加载与隔离⼀、 FatJar概念⼆、FatJar的加载三、FatJar的隔离四、隔离机制验证五、 FatJar的定位六、 打包注意点 序 今天整理旧电脑里的资料,偶然翻到大概10年前实习时写的笔记,之前经常遇到Java依赖冲突的问题…...
Spring MVC笔记
01 什么是Spring MVC Spring MVC 是 Spring 框架中的一个核心模块,专门用于构建 Web 应用程序。它基于经典的 MVC 设计模式(Model-View-Controller),但通过 Spring 的特性(如依赖注入、注解驱动)大幅简化了…...
BurpSuite插件jsEncrypter使用教程
一、前言 在当今Web应用安全测试中,前端加密已成为开发者保护敏感数据的常用手段。然而,这也给安全测试人员带来了挑战,传统的抓包方式难以获取明文数据,测试效率大打折扣。BurpSuite作为一款强大的Web安全测试工具,其…...
【C#实现手写Ollama服务交互,实现本地模型对话】
前言 C#手写Ollama服务交互,实现本地模型对话 最近使用C#调用OllamaSharpe库实现Ollama本地对话,然后思考着能否自己实现这个功能。经过一番查找,和查看OllamaSharpe源码发现确实可以。其实就是开启Ollama服务后,发送HTTP请求&a…...
Android Glide 框架线程管理模块原理的源码级别深入分析
一、引言 在现代的 Android 应用开发中,图片加载是一个常见且重要的功能。Glide 作为一款广泛使用的图片加载框架,以其高效、灵活和易用的特点受到了开发者的青睐。其中,线程管理模块是 Glide 框架中至关重要的一部分,它负责协调…...
每天记录一道Java面试题---day32
MySQL索引的数据结构、各自优劣 回答重点 B树:是一个平衡的多叉树,从根节点到每个叶子节点的高度差不超过1,而且同层级的节点间有指针相互连接。在B树上的常规检索,从根节点到叶子节点的搜索效率基本相当,不会出现大…...
Vue3 Pinia 符合直觉的Vue.js状态管理库
Pinia 符合直觉的Vue.js状态管理库 什么时候使用Pinia 当两个关系非常远的组件,要传递参数时使用Pinia组件的公共参数使用Pinia...
深度学习与大模型基础-向量
大家好!今天我们来聊聊向量(Vector)。别被这个词吓到,其实向量在我们的生活中无处不在,只是我们没注意罢了。 1. 向量是什么? 简单来说,向量就是有大小和方向的量。比如你从家走到学校&#x…...
【网络编程】完成端口 IOCP
10.11 完成端口 10.11.1 基本概念 完成端口的全称是I/O 完成端口,英文为IOCP(I/O Completion Port) 。IOCP是一个异 步I/O 的 API, 可以高效地将I/O 事件通知给应用程序。与使用select() 或是其他异步方法不同 的是,一个套接字与一个完成端口关联了起来…...
《苍穹外卖》SpringBoot后端开发项目重点知识整理(DAY1 to DAY3)
目录 一、在本地部署并启动Nginx服务1. 解压Nginx压缩包2. 启动Nginx服务3. 验证Nginx是否启动成功: 二、导入接口文档1. 黑马程序员提供的YApi平台2. YApi Pro平台3. 推荐工具:Apifox 三、Swagger1. 常用注解1.1 Api与ApiModel1.2 ApiModelProperty与Ap…...
接口测试中缓存处理策略
在接口测试中,缓存处理策略是一个关键环节,直接影响测试结果的准确性和可靠性。合理的缓存处理策略能够确保测试环境的一致性,避免因缓存数据导致的测试偏差。以下是接口测试中常见的缓存处理策略及其详细说明: 一、缓存处理的核…...
MPNet:旋转机械轻量化故障诊断模型详解python代码复现
目录 一、问题背景与挑战 二、MPNet核心架构 2.1 多分支特征融合模块(MBFM) 2.2 残差注意力金字塔模块(RAPM) 2.2.1 空间金字塔注意力(SPA) 2.2.2 金字塔残差块(PRBlock) 2.3 分类器设计 三、关键技术突破 3.1 多尺度特征融合 3.2 轻量化设计策略 3.3 抗噪声…...
AI Agent与Agentic AI:原理、应用、挑战与未来展望
文章目录 一、引言二、AI Agent与Agentic AI的兴起2.1 技术契机与生态成熟2.2 Agent的定义与特征2.3 Agent的发展历程 三、AI Agent的核心技术栈解密3.1 感知模块代码示例:使用Python和OpenCV进行图像识别 3.2 认知与决策模块代码示例:使用OpenAI GPT-3进…...
关于 WASM:1. WASM 基础原理
一、WASM 简介 1.1 WebAssembly 是什么? WebAssembly(WASM) 是一种能在现代浏览器中高效运行的二进制指令格式,它不是传统的编程语言,而是一种 低级字节码格式,可由高级语言(如 C、C、Rust&am…...
佰力博科技与您探讨热释电测量的几种方法
热释电的测量主要涉及热释电系数的测定,这是表征热释电材料性能的重要参数。热释电系数的测量方法主要包括静态法、动态法和积分电荷法。其中,积分电荷法最为常用,其原理是通过测量在电容器上积累的热释电电荷,从而确定热释电系数…...
Aspose.PDF 限制绕过方案:Java 字节码技术实战分享(仅供学习)
Aspose.PDF 限制绕过方案:Java 字节码技术实战分享(仅供学习) 一、Aspose.PDF 简介二、说明(⚠️仅供学习与研究使用)三、技术流程总览四、准备工作1. 下载 Jar 包2. Maven 项目依赖配置 五、字节码修改实现代码&#…...
LabVIEW双光子成像系统技术
双光子成像技术的核心特性 双光子成像通过双低能量光子协同激发机制,展现出显著的技术优势: 深层组织穿透能力:适用于活体组织深度成像 高分辨率观测性能:满足微观结构的精细研究需求 低光毒性特点:减少对样本的损伤…...
高考志愿填报管理系统---开发介绍
高考志愿填报管理系统是一款专为教育机构、学校和教师设计的学生信息管理和志愿填报辅助平台。系统基于Django框架开发,采用现代化的Web技术,为教育工作者提供高效、安全、便捷的学生管理解决方案。 ## 📋 系统概述 ### 🎯 系统定…...
企业大模型服务合规指南:深度解析备案与登记制度
伴随AI技术的爆炸式发展,尤其是大模型(LLM)在各行各业的深度应用和整合,企业利用AI技术提升效率、创新服务的步伐不断加快。无论是像DeepSeek这样的前沿技术提供者,还是积极拥抱AI转型的传统企业,在面向公众…...
快速排序算法改进:随机快排-荷兰国旗划分详解
随机快速排序-荷兰国旗划分算法详解 一、基础知识回顾1.1 快速排序简介1.2 荷兰国旗问题 二、随机快排 - 荷兰国旗划分原理2.1 随机化枢轴选择2.2 荷兰国旗划分过程2.3 结合随机快排与荷兰国旗划分 三、代码实现3.1 Python实现3.2 Java实现3.3 C实现 四、性能分析4.1 时间复杂度…...
