我们在程序中经常需要对数据列表进行排序,有时候使用SOQL的order by 不一定能完全符合需求,需要对数据进行排序,排序可以有多种方式,不同的方式针对不同的场景。篇一只是简单的描述一下选择排序,插入排序以及插入排序优化版--希尔排序。

一.选择排序

选择排序的中心思想为第一轮找到数组中最小的值,将最小值和第一个元素交换位置,第二轮找到剩余数组的最小值,将其和第二个元素交换,以此类推。

选择排序的特点如下:

1.比较次数:n * (n-1) / 2
2.交换次数:N
4.运行时间和输入无关
5.数据移动次数是最小的,每次移动都只会改变两个数组的值

apex不像java,基础类型类似Integer,String等均没有实现Comparable接口,所以方法中均已Integer类型进行处理,有兴趣的可以自行修改成Comparable或者其他类型。

 public static Integer[] selectionSort(Integer[] datas) {
Integer dataLength = datas.size();
for(Integer i = 0;i < dataLength;i++) {
Integer min = i;
for(Integer j = i + 1;j < dataLength;j++) {
if(datas[min] > datas[j]) {
min = j;
}
}
Integer temp = datas[i];
datas[i] = datas[min];
datas[min] = temp;
}
return datas;
}

实现Comparable接口的代码:

 public static Comparable[] selectionSort1(Comparable[] datas) {
Integer dataLength = datas.size();
for(Integer i = 0;i < dataLength;i++) {
Integer min = i;
for(Integer j = i;j < dataLength;j++) {
if(datas[min].compareTo(datas[j]) > 0) {
min = j;
}
}
Comparable temp = datas[i];
datas[i] = datas[min];
datas[min] = temp;
}
return datas;
}

二.插入排序

插入排序的中心为对左边的第i(i在1~n之间)项进行排序,保证前i项是有序的,等排到最右边一位,则整个数组变为有序的数列。

插入排序特点:

比较次数:N^2/4
 交换次数:N^2/4
 所需时间取决于数组元素的初始顺序,如果初始顺序相对有序,排序会快很多
 插入排序适用情景:
 1.数组中的每个元素距离他的最终位置不远
 2.一个有序的大数组接一个小数组
 3.数组中只有几个元素位置不正确
 实现规则:每一轮都对左边的i项数据进行排序,保证前i项有序
代码如下:

     public static Integer[] insertionSort(Integer[] datas) {
Integer dataLength = datas.size();
for(Integer i = 1;i < dataLength;i++) {
for(Integer j = i; j > 0 && datas[j] < datas[j-1];j--) {
Integer temp = datas[j-1];
datas[j-1] = datas[j];
datas[j] = temp;
}
}
return datas;
}

三.希尔排序

插入排序适用于数组中只有几个元素不正确,但是如果最小的一位如果在数组的最后一位,相当于需要移动N个位置。希尔排序可以用于快速交换不相邻的元素以对数组的局部进行排序,思想为使数组中任意间隔为H的元素都是有序的。一个H有序数组就是H个互相独立的有序数组放在一起形成的一个数组。如果H很大,我们就可以将元素一次移动到很远的地方。H取值可以取2,3,4...n

关于希尔排序可以查看:https://baike.baidu.com/item/%E5%B8%8C%E5%B0%94%E6%8E%92%E5%BA%8F/3229428?fr=aladdin

下面代码描述为当H为3的排序  元素的间隔规律为a[n+1] = a[n] + 3 ^ n

public static String[] shellSort(String[] datas) {
Integer dataLength = datas.size();
Integer h = 1;
while(h < dataLength/3) {
h = 3 * h + 1;//1,4,13,40 ...
}
System.debug(LoggingLevel.INFO, '*** h: ' + h);
System.debug(LoggingLevel.INFO, '*** dataLength: ' + dataLength);
while(h >= 1) {
for(Integer i = h;i < dataLength;i++) {
//将a[i]插入到a[i-h],a[i-2h],a[i-3h] ....中
for(Integer j = i;j >= h && datas[j] < datas[j-h];j -= h) {
String temp = datas[j-h];
datas[j-h] = datas[j];
datas[j] = temp;
}
System.debug(LoggingLevel.INFO, '*** i: ' + i);
}
System.debug(LoggingLevel.INFO, '*** datas: ' + String.valueOf(datas));
System.debug(LoggingLevel.INFO, '*** h: ' + h);
h = h / 3; }
return datas;
}

当数组为 S H E L L S O R T E X A M P L E 情况下,使用H为3的每次运行如下图,图不全,内容自己补充。

运行后,可以将数组排成升序的有序列表。

总结:此三种排序方式,单纯效率考虑的话,可以使用希尔排序,优化了插入排序的不足,同时没有特别的占用内存。篇二会描述一下其他排序方式。额,题外话,还是不太希望今天有人看到这篇博客的,祝大家七夕快乐。

salesforce零基础学习(七十九)简单排序浅谈 篇一的更多相关文章

  1. salesforce零基础学习(九十八)Type浅谈

    在Salesforce的世界,凡事皆Metadata. 先通过一句经常使用的代码带入一下: Account accountItem = (Account)JSON.deserialize(accoun ...

  2. salesforce 零基础学习(十九)Permission sets 讲解及设置

    Permission sets以及Profile是常见的设置访问权限的方式. Profile规则为'who see what'.通过Profile可以将一类的用户设置相同的访问权限.对于有着相同Pro ...

  3. salesforce零基础学习(九十九)Git 在salesforce项目中的应用(vs code篇)

    本篇参考: https://code.visualstudio.com/docs/editor/versioncontrol https://git-scm.com/doc https://git-s ...

  4. salesforce 零基础学习(十八)WorkFlow介绍及用法

    说起workflow大家肯定都不陌生,这里简单介绍一下salesforce中什么情况下使用workflow. 当你分配许多任务,定期发送电子邮件,记录修改时,可以通过自动配置workflow来完成以上 ...

  5. salesforce零基础学习(九十九)Salesforce Data Skew(数据倾斜)

    本篇参考: https://developer.salesforce.com/blogs/engineering/2013/04/managing-lookup-skew-to-avoid-recor ...

  6. salesforce 零基础学习(十六)Validation Rules & Date/time

    上一篇介绍的内容为Formula,其中的Date/time部分未指出,此篇主要介绍Date/time部分以及Validation rules. 本篇参考PDF: Date/time:https://r ...

  7. salesforce零基础学习(八十九)使用 input type=file 以及RemoteAction方式上传附件

    在classic环境中,salesforce提供了<apex:inputFile>标签用来实现附件的上传以及内容获取.salesforce 零基础学习(二十四)解析csv格式内容中有类似的 ...

  8. salesforce零基础学习(八十)使用autoComplete 输入内容自动联想结果以及去重实现

    项目中,我们有时候会需要实现自动联想功能,比如我们想输入用户或者联系人名称,去联想出系统中有的相关的用户和联系人,当点击以后获取相关的邮箱或者其他信息等等.这种情况下可以使用jquery ui中的au ...

  9. salesforce 零基础学习(五十二)Trigger使用篇(二)

    第十七篇的Trigger用法为通过Handler方式实现Trigger的封装,此种好处是一个Handler对应一个sObject,使本该在Trigger中写的代码分到Handler中,代码更加清晰. ...

随机推荐

  1. MySQL oracle 分页

    (1)MySql的Limit m,n语句 Limit后的两个参数中,参数m是起始下标,它从0开始:参数n是返回的记录数.我们需要分页的话指定这两个值即可. 比如:查询10行记录,起始行从3开始 SEL ...

  2. ActiveMQ结合WebScoket应用例子以及介绍

    一.ActiveMQ的介绍? 1.JMS基础概念 JMS(java Message Service) 即使java消息服务,它提供标准的产生.发送.接收的接口简化企业应用开发,它支持两种消息通信模型: ...

  3. vue 自定义组件

    1.Vue.component('component-test', { props:{}, data:function(){ return{} }, mounted:function(){}, com ...

  4. javaSE 第77节课

    1.InetAddress InetAddress是地址的封装类,也可通过它来获得当前的操作地址(1)获得电脑当前上网的IP地址 (2)与服务器连接操作 (3) 二.MD5加密文件 文件本地秒传操作例 ...

  5. 51nod_1831: 小C的游戏(Bash博弈 找规律)

    题目链接 此类博弈不需要考虑sg函数,只需要确定必胜态和必败态,解题思路一般为打败先打表找规律,而后找规律给出统一的公式.打表方式:给定初始条件(此题中为ok[0]=ok[1]=0),然后从低到高枚举 ...

  6. JavaScript中Function原型及其prototype属性的简单应用

    大家都知道在JavaScript中是没有类的概念的,但是却是有对象的概念的.有的人可能理解对象和类有些迷糊,这里简单的概括一下他们之间的区别: 类:抽象的概念,例如人,动物,汽车等都可以抽象成一个类 ...

  7. (转)ZXing生成二维码和带logo的二维码,模仿微信生成二维码效果

    场景:移动支付需要对二维码的生成与部署有所了解,掌握目前主流的二维码生成技术. 1 ZXing 生成二维码 首先说下,QRCode是日本人开发的,ZXing是google开发,barcode4j也是老 ...

  8. 云游戏学习与实践(二)——安装GamingAnywhere

    安装GamingAnywhere 一.GamingAnywhere项目 GamingAnywhere是一个开源的实现云游戏的引擎,并且高效.跨平台.易扩展.可调配. GitHub地址:https:// ...

  9. 相对路径&绝对路径

    粗浅理解: 1)绝对路径:带有访问协议的路径,就是带上http访问协议 2)相对路径: ①以带斜杠开头的相对路径: A)前台相对路径:以web服务器的根路径为参照路径,比如在jsp.HTML中写的路径 ...

  10. 解决 lispbox macOS 不兼容问题

    误打误撞,解决了很重要的入门级问题,简要记录下. lispbox 官网末尾说目前暂不兼容 10.4 以上系统: TODO: Compile on Mac OS X 10.4, for compatab ...