介绍堆排序及其应用,topk问题,优先级队列等。
优先队列:
优先队列有两个基本的操作:
1、删除最大元素
2、插入新的元素
优先队列的应用场景很多,比如用于定时任务的调度,我们有一个定时任务的调度序列,现在新加入了一个新的定时任务,需要把它放到队列中合适的位置,实际上就是优先级队列的使用。另外,还有在图搜索算法,数据压缩上面的应用。
下面是一个优先队列的API及其实现
public class MaxPQ <Key extends Comparable<Key>> {
private Key[] pq;
private int N=0;
//0位置不放置元素
MaxPQ(int max){
pq=(Key[]) new Comparable[max+1];
}
void insert(Key v){
//调整数组大小 为原先的2倍
if(N+1==pq.length){
resize(2*pq.length);
}
pq[++N]=v;
swim(N);
}
Key max(){
return pq[1];
}
Key delMax(){
Key max=pq[1];
swap(1,N--);
sink(1);
pq[N+1]=null;
if(N>0 && N+1==pq.length/4){
resize(pq.length/2);
}
return max;
}
boolean isEmpty(){
return N==0;
}
int size(){
return N;
}
private void swim(int k){
while(k>1 && less(k/2,k)){
swap(k/2,k);
k=k/2;
}
}
private void sink(int k){
while(2*k<=N){
int j=2*k;
if(j+1<=N && less(j,j+1)){
j++;
}
if(less(k,j)){
swap(k,j);
//向下移动
k=j;
}else {
break;
}
}
}
private void swap(int i,int j){
Key a=pq[i];
pq[i]=pq[j];
pq[j]=a;
}
private boolean less(int i,int j){
return pq[i].compareTo(pq[j])<0;
}
private void resize(int max){
Key[] temp=(Key[]) new Comparable[max];
for(int i=1;i<=N;i++){
temp[i]=pq[i];
}
pq=temp;
}
public static void main(String[] args) {
MaxPQ pq=new MaxPQ(4);
pq.insert("P");
pq.insert("Q");
pq.insert("E");
String s=(String)pq.delMax();
System.out.println(s);
pq.insert("X");
pq.insert("A");
pq.insert("M");
System.out.println(pq.delMax());
pq.insert("P");
pq.insert("L");
pq.insert("E");
System.out.println(pq.delMax());
System.out.println(pq.max());
}
}
用于堆排序,主要有两个操作,一个是构建有序堆,一个是堆中最大元素的下沉
构建有序堆比如大根堆,可以从最后一个非叶子节点开始进行构造,将其下沉比较,最终获得一个小型的堆,最后构建整个堆结构。
public class HeapSort {
public void heapSort(Comparable[] a){
int index=a.length-1;
//构建有序堆
for(int i=(index-1)/2;i>=0;i--){
sink(a,i,index);
}
for(int i=index;i>=0;i--){
swap(a,0,index--);
sink(a,0,index);
}
}
//N是最后一个元素的位置
public void sink(Comparable[] a,int k,int N){
while(2*k+1<=N){
int j=2*k+1;
if(j+1<=N && less(a,j,j+1)){
j++;
}
if(less(a,k,j)){
swap(a,k,j);
k=j;
}else{
break;
}
}
}
private boolean less(Comparable[] a,int i,int j){
return a[i].compareTo(a[j])<0;
}
private void swap(Comparable[] a,int i,int j){
Comparable temp=a[i];
a[i]=a[j];
a[j]=temp;
}
public static void main(String[] args) {
Integer[] a=new Integer[]{0,2,1,4,3,7,9,6,5,0};
HeapSort s=new HeapSort();
s.heapSort(a);
for(int i=0;i<a.length;i++){
System.out.print(a[i]+" ");
}
}
}