|
|

分享源码
| 界面截图: |
|
| 是否带模块: |
纯源码 |
| 备注说明: |
- |
本帖最后由 APPLEUFO 于 2026-5-25 23:54 编辑
自定义数组排序的时候,其实不用移动所有成员,大费周章 千问ai 提供了这种思路 使用索引下标 ,不用把整个自定义数据全部移动一遍
(完美避开了频繁移动庞大的自定义数据(结构体),只交换轻量的整数下标,在处理海量数据时性能极佳)
例程里加入了一个索引。
.版本 2
.数据类型 自定义数据类型_数据
.成员 身高, 整数型
.成员 体重, 整数型
.成员 排序索引, 整数型
与其加一个不相关的数组,不如就把索引塞在成员后面,这个成员专门放索引
其实身高 体重 你可以添加 两个索引。每种排序占用一个索引,就不会在你体重排序的时候 , 把身高排序的索引都重置了。下回用又得重新排
明白了。你看这样怎么样,自定义数据类型如果要排序,我就先把要排序的数据成员全取出来,再加一个索引数组,里面填1-100,这样的其他数据成员的个数
再用快排把数据成员排一下,在这个时候,把这个索引数组也放在快拍里一起变动
快排结束后,就得到一组索引数组了。
用这组索引数组,再建立一个空的自定义数据类型
就能把原本的自定义数据类型,一个个填充到一个 空的自定义数据类型里面
你的思路非常清晰,完全抓住了“索引排序”的核心精髓!
你提出的这个方法,在计算机科学里有一个专门的名词,叫做“间接排序”。它最大的优点就是完美避开了频繁移动庞大的自定义数据(结构体),只交换轻量的整数下标,在处理海量数据时性能极佳。
不过,针对你提到的最后一步——“用这组索引数组,再建立一个空的自定义数据类型,把原本的数据一个个填充进去”,我想给你一个更优化的建议:
?? 优化建议:直接“按单取货”,省去“二次搬运”
其实,当你通过快排得到了那组排好序的索引数组(也就是你说的挂号单)之后,通常根本不需要再创建一个全新的、填满数据的自定义数组。
因为那张“挂号单”已经包含了所有的顺序信息。在任何需要用到排序后数据的地方,你只需要拿着这张单子去原数组里取值即可。这样做不仅省去了最后那次大规模的数据拷贝和内存分配,代码也更灵活。
为了让你看得更明白,我把你的思路整理成了一段易语言的伪代码,你可以对比一下看看其中的区别:
' 假设这是原本的庞大自定义数组(包含姓名、年龄、成绩等一堆数据)
.局部变量 原始数据组, 学生类型, , "100"
' ...这里省略了给原始数据组赋值的代码...
' --- 第一步:准备要排序的数值数组 和 索引数组 ---
.局部变量 待排成绩, 小数型, , "100" ' 把你说的“要排序的数据成员全取出来”
.局部变量 索引数组, 整数型, , "100" ' 填好1到100的初始下标
.计次循环首 (100, i)
待排成绩 = 原始数据组.成绩
索引数组 = i
.计次循环尾 ()
' --- 第二步:快排(同时变动两个数组)---
' 这里的快排逻辑是:当需要交换“待排成绩”和“待排成绩[j]”时
' 必须同步交换“索引数组”和“索引数组[j]”!
' 这样排完序后,索引数组里的下标顺序,就对应了成绩从高到低的顺序。
调用_快速排序_双数组联动 (待排成绩, 索引数组)
' --- 第三步:使用结果(重点看这里!)---
' ? 你的方案(二次搬运):
' 建立一个新数组,把原始数据按照索引数组的顺序重新拷贝一遍。
' 缺点:又进行了一次大规模的内存拷贝,浪费了前面省下的性能。
.局部变量 最终排序数组, 学生类型, , "100"
.计次循环首 (100, i)
最终排序数组 = 原始数据组[索引数组]
.计次循环尾 ()
' ? 推荐的方案(按单取货):
' 直接在需要的地方,拿着索引数组去原始数据组里取值!
.局部变量 i, 整数型
.计次循环首 (100, i)
' 比如要打印成绩单,或者显示在超级列表框里:
调试输出 ("第" + 到文本(i) + "名是:" + 原始数据组[索引数组].姓名 + ",成绩:" + 到文本(原始数据组[索引数组].成绩))
.计次循环尾 ()
?? 总结一下你的这套流程
1. 抽取与初始化:把要比较的那个字段(比如成绩)抽出来,并准备好对应的 1, 2, 3... 索引数组。
2. 联动快排:写一个能同时操作两个数组的快排。比较大小时只看“成绩数组”,但一旦触发交换,连“索引数组”的下标也跟着一起换位置。
3. 按需读取:拿到最终的索引数组后,把它当成一把“钥匙”。以后无论在哪里需要有序的数据,就用这把钥匙去开原始数据的大门(原始数据组[索引数组])。
你的整体架构已经完全没问题了,只要把最后一步的“物理搬运”改成“逻辑引用”,这套排序方案在易语言里处理几万甚至几十万条复杂数据时,都会非常丝滑!
|
|