算法排序2-基本排序方法2
5. 快速排序
- 快速排序是实现简单,使用于各种不同的输入数据且在一般应用中比其他排序算法都要快的多,
- 快速排序也是一种分治的排序算法,
- 在快速排序,,,你可以使用很多的辅助的方法,去实行快速排
- 原地切分
- 别越界
- 保持随机性
- 终止循环
- 处理切分元素值有重复的情况
- 终止递归
- 但是 如果主键是重复的项多的情况下,时间复杂度会是递增的
- 它将一个数组分成两个子数组,将两部分独立的排序,,在快速排序中,切分的位置取决于数组的内容
public static void sort(Comparable[] a){
StdRandom.shuffle(a);
sort(a,0,a.length-1);
}
private static void sort(Comparable[] a, int lo,int hi){
if (hi <= lo){
return;
}
int j= partition(a,lo,hi);
sort(a,lo,j-1);
sort(a,j+1,hi);
}
private static int partition(Comparable[] a, int lo, int hi) {
int i = lo , j = hi+1;
Comparable v = a[lo];
while (true){
while (less(a[++i],v)){
if (i == hi){
break;
}
}
while (less(v,a[--j])){
if (j == lo){
break;
}
}
if (i >= j){
break;
}
exch(a,i,j);
}
exch(a,lo,j);
return j;
}
- 算法的改进
- 切换到插入排序
- 三取样切分
- 熵最优的排序
// 三向区分的快速排序
class Quick3way{
private static void sort(Comparable[] a, int lo , int hi){
if (hi <= lo){
return;
}
int lt = lo,i=lo+1,gt = hi;
Comparable v = a[lo];
while (i <= gt){
int cmp = a[i].compareTo(v);
if (cmp <0){
exch(a,lt++,i++);
}else if (cmp > 0){
exch(a,i,gt--);
}else {
i++;
}
}
sort(a,lo,lt-1);
sort(a,gt+1,hi);
}
}
6. 优先队列
- 不是每个程序,都需要排序整个数组,或许有那么多只需要查找最大的元素,,在这种的情况下,一个合适的数据结构应该支持 两种操作 : 删除最大元素和插入元素。
- 而优先队列最重要的操作就是***删除最大元素***和***插入元素***
1. API
-
泛型优先队列的API -----MaxPQ
-
关联索引的泛型优先队列的API — IndexMinPQ
- 这个结构 可以能够快速访问其中最小元素的数组,
- 它能够快速访问数组的一个特定子集中的最小元素(指所有被插入的元素)
2. 堆
1. 堆的定义
-
数据结构二叉堆能够很好的实现优先队列的基本操作,
-
在二叉堆的数组中,每个元素都要保证大于等于另两个特定位置的元素
-
当一颗二叉树的每个结点都大于等于它的两个子结点,可说这个堆有序
2. 一些特殊的代码实现
-
基于堆的优先队列
package com.sort.priority.queue; /** * Created by IntelliJ IDEA. * * @version : 1.0 * @auther : Firewine * @mail : 1451661318@qq.com * @Program Name: MaxPQ .java * @Create : 2019-02-25-19:21 * @Description : 基于堆的优先队列 */ public class MaxPQ<key extends Comparable<key>> { private key[] pq; private int N = 0; public MaxPQ(int maxN){ pq = (key[]) new Comparable[maxN +1]; } public boolean isEmpty(){ return N == 0; } public int size(){ return N; } public void insert(key v){ pq[++N] =v; swim(N); } public key delMax(){ key max = pq[1]; exch(1, N--); pq[N+1] = null; sink(1); return max; } private boolean less(int i,int j){ return pq[i].compareTo(pq[j] ) < 0; } private void exch(int i,int j){ key t = pq[i]; pq[i] = pq[j]; pq[j] = t; } /** * 由下至上的堆有序化 * @param k */ private void swim(int k){ while (k>1 && less(k/2,k)){ exch(k/2,k); } } /** * 由上之下的堆有序化 * @param k */ private void sink(int k){ while (2*k <= N){ int j = 2*k; if (j < N && less(j,j+1)){ j++; } if (!less(k,j)){ break; } exch(k,j); k = j; } } }
-
索引优先队列用例 —使用优先队列的多项归并
package com.sort.priority.queue; import edu.princeton.cs.algs4.In; import edu.princeton.cs.algs4.IndexMinPQ; import edu.princeton.cs.algs4.StdOut; /** * Created by IntelliJ IDEA. * * @version : 1.0 * @auther : Firewine * @mail : 1451661318@qq.com * @Program Name: Multiway .java * @Create : 2019-02-25-19:35 * @Description : */ public class Multiway { public static void merge(In[] streams) { int N = streams.length; IndexMinPQ<String> pq = new IndexMinPQ<>(N); for (int i = 0; i < N; i++) { if (!streams[i].isEmpty()) { pq.insert(i, streams[i].readString()); } } while (!pq.isEmpty()) { StdOut.println(pq.delMin()); int i = pq.delMin(); if (!streams[i].isEmpty()) { pq.insert(i, streams[i].readString()); } } } public static void main(String[] args) { int N = args.length; In[] streams = new In[N]; for (int i=0;i<N;i++){ streams[i] = new In(args[i]); } merge(streams); } }
-