2.5应用
在一个有序的数组中查找一个元素要比在一个无序的数组中查找简单得多
2.5.1 将各种数据排序
Java可以实现任意实现了Comparable接口的数据类型排序,不管数据类型是什么;
只要实现Comparable接口就可以用任意排序算法;
实现Comparable接口的方法:定义一个compareTo()函数,并在其中定义该数据类型中的大小关系;
Java中指针操作是隐式的,除了原始数字类型外,操作的总是数据的引用(指针);
使用引用的好处是不必移动整个元素,对于元素大而键小的数组来说可以节约时间空间;
用做键的数据类型是不可变的;
Comparator接口允许在一个类中实现多种排序(依据不同属性的排序);
用Compartor接口可以定义多种比较器;
排序的稳定性:保留数组中重复元素的相对位置;
稳定的排序算法:插入排序、归并排序
不稳定的排序算法:希尔排序、选择排序、快速排序、堆排序;
在稳定性是必要的情况下,稳定排序算法才有优势
2.5.2 选择哪种排序算法
快速排序是最快的通用排序算法,大多情况下选择快速排序
要求稳定性而空间不是问题,选择归并排序
2.5.2.1将原始数据类型排序
对原始数据类型排序,将Comparable接口替换为原始数据类型名,重新定义less()方法或将less()的地方换成a[i]<a[j],这样可以将原始类型数据更快地排序
2.5.2.2 java系统库的排序算法
Java系统库的主要排序方法java.util.Arrays.sort(),对原始数据类型使用三向快速排序,对引用类型使用归并排序
Java系统库中的优先队列数据类型:java.util.PriorityQueue
2.5.3 问题的规约
规约:为解决某个问题而发明的方法,正好可以用来解决另一个问题
用排序的方法来解决其他的问题,是规约的一个例子
一些问题如果先排序,再解决,会降低时间复杂度
1.5.3.1 找出重复元素
1.5.3.2 排名
1.5.3.3 优先队列
1.5.3.4 中位数与顺序统计
找出数组中第k小的元素的方法:
1.优先队列,找到topK;
2.将整个数组排序
3.代码如下:
public static Comparable select(Comparable[] a, int k){ StdRandom.shuffle(a); int lo = 0,hi = a.length - 1; while(hi > lo){ int j = partition(a,lo,hi); if(j == k) return a[k]; if(j > k) hi = j -1; if(j < k) lo = j +1; } return a[k]; }
算法解释:
1) partition()方法,将a[lo:hi]重新排列返回j,使得a[lo:j-1]<=a[j]<=a[j+1:hi];
2) 如果j ==k ,则找到第k小的元素
3) 如果j > k,则切分左边的数组
4) 如果j < k,则切分右边的数组
5) 最终得到的a[k],a[0:k-1]<=a[k]<=a[k+1:a.length-1]
平均来说,基于切分的选择算法的运行时间是线性的
2.5.4 排序应用一览
商业计算
信息搜索
运筹学
数值计算
组合搜索
Prim算法Dijkstra算法
Kruskal算法
霍夫曼亚索
字符串处理