由于一直做Android开发,项目当中很少用到高效的查找,排序算法。移动端的数据量小,顶天了一千条数据,用个for while循环全集遍历,也很够用,根本不需要什么二分查找什么归纳排序这些高效算法。所以移动开发这一块重点不在这里。
但是学了看了那没多的算法,不用一下实在可惜,于是今天就尝试写了一下归纳排序算法,也仅仅是demo,大家不要笑话。
网上很多算法都是针对基本类型的集合,但是现实当中这种情况是很少的,我们一般项目里用到的数据都是自定义的一些对象,所以这里我也写了一个AA类来做排序的对象。
public static class AA implements Comparable<String> {
String str;
public AA(String s){
str=s;
}
public String getStr() {
return str;
}
public void setStr(String str) {
this.str = str;
}
//重写这个比较方法,用于定义比较两个AA对象的大小的规则
@Override
public int compareTo(String s) {
int len1=this.str.length();
int len2=s.length();
return (len1 < len2) ? -1 : ((len1 == len2) ? 0 : 1);
}
}
现实的项目里会对一个无序的集合进行排序
List<AA> array = new ArrayList<>();
int i=1000;//这里模拟插入9000个数据到列表里
while (i>0){
i--;
array.add(new AA("5"));
array.add(new AA("69"));
array.add(new AA("12"));
array.add(new AA("3"));
array.add(new AA("56"));
array.add(new AA("789"));
array.add(new AA("2"));
array.add(new AA("5648"));
array.add(new AA("23"));
}
MergeSortTest mergeSortTest = new MergeSortTest();
Log.i(TAG,"开始时间:"+System.currentTimeMillis());
mergeSortTest.sort3(array, 0, array.size()-1);
Log.i(TAG,"结束时间:"+System.currentTimeMillis());
System.out.println("排序后的数组:size "+array.size());
for (int m = 0; m <= array.size()-1; m++) {
System.out.print(array.get(m).getStr() + "\t");
}
System.out.println();
递归方法
//这个递归方法的执行很多人会搞晕,其实它是类似洋葱的一种执行方法(一层包一层):
sort3__
|sort3__
|sort3__
|sort3__
|sort3.....
最外面一层会一直等待里面那一层调用的返回
public void sort3(List<AA> array, int left, int right) {
if (left >= right){
return;
}
// 找出中间索引
int center = (left + right) / 2;
// 对左边数组进行递归
sort3(array, left, center);
// 对右边数组进行递归
sort3(array, center + 1, right);
// 合并
merge3(array, left, center, right);
// 打印每次排序结果
for (int i = 0; i < array.size(); i++) {
// System.out.print(array.get(i).getStr() + "\t");
}
System.out.println();
}
合并集合
public void merge3(List<AA> array, int left, int center, int right) {
// 临时数组
List<AA> tmpArr=new ArrayList<>();
for(int i=0;i<array.size();i++){
tmpArr.add(array.get(0));
}
// 右数组第一个元素索引
int mid = center + 1;
// third 记录临时数组的索引
int third = left;
// 缓存左数组第一个元素的索引
int tmp = left;
while (left <= center && mid <= right) {
// 从两个数组中取出最小的放入临时数组
int cp=array.get(left).compareTo(array.get(mid).getStr());
// int cp=Integer.compare(array.get(left),array.get(mid));
if (cp==-1||cp==0) {
tmpArr.set(third++,array.get(left++));
} else {
tmpArr.set(third++,array.get(mid++));
}
}
// 剩余部分依次放入临时数组(实际上两个while只会执行其中一个)
while (mid <= right) {
tmpArr.set(third++,array.get(mid++));
}
while (left <= center) {
tmpArr.set(third++,array.get(left++));
}
// 将临时数组中的内容拷贝回原数组中
// (原left-right范围的内容被复制回原数组)
while (tmp <= right) {
array.set(tmp,tmpArr.get(tmp++));
}
}