优先队列解决的取所有输入取前n位或者后n位,n值较小,放入队列中保存,方便后续作运算或者其他用途。
利用堆实现优先队列,再时间上比利用数组的排序实现更加省时间,数组的排序是线性N,而堆只需要lgN。
下面是利用实现堆实现优先队列和排序的类,测试输出为
19
18 13
16 17 10 12
9 15 8 7 1 5 4 11
0 6 3 14 2
//最大元素队列出队
18
17 13
16 8 10 12
9 15 2 7 1 5 4 11
0 6 3 14
//最大元素队列出队
17
16 13
15 8 10 12
9 14 2 7 1 5 4 11
0 6 3
[6, 2, 3, 4, 9, 11, 15, 16, 1, 6]
//堆初始化
[16, 9, 15, 4, 6, 11, 3, 2, 1, 6]
//利用优先队列原理,不断sink排序
[1, 2, 3, 4, 6, 6, 9, 11, 15, 16]
public class CompletedSortedStack<T extends Comparable<T>> {
private T[] stack;
private int num = 0;
private int capacity = 16;
public CompletedSortedStack(int initialLen){
this.stack = (T[]) new Comparable[initialLen];
}
public CompletedSortedStack(){
this.stack = (T[]) new Comparable[capacity];
}
//from root to the bottom
private void sink(int index){
while(index >= 1 && index*2 <= num){
int exeCNode = index*2;
if(stack[exeCNode +1] != null && stack[exeCNode].compareTo(stack[exeCNode +1]) < 0)
exeCNode = exeCNode +1;
if(stack[exeCNode].compareTo(stack[index]) > 0)
SelectionSort.exchange(stack, exeCNode, index);
else
break;
index = exeCNode;
}
}
//from the bottom to the root
private void swim(int index){
while(index > 1 && index <= num && stack[index/2].compareTo(stack[index]) < 0 ){
SelectionSort.exchange(stack, index/2, index);
index = index/2;
}
}
public int size(){
return this.num;
}
public boolean isEmpty(){
return this.num == 0;
}
public T deleteMax(){
T max = stack[1];
stack[1] = this.stack[num--];
stack[num+1] = null;
sink(1);
return max;
}
public void insert(T value){
if (value != null) {
judeEnableCapacity();
stack[++num] = value;
}
swim(this.num);
}
private void judeEnableCapacity(){
if(capacity*0.8 < num){
capacity = capacity *2;
T[] oldStack = stack;
stack = (T[]) new Comparable[capacity];
for(int i = 1; i <= num; i++){
stack[i] = oldStack[i];
}
}
}
private String getSpace(int num){
StringBuilder space = new StringBuilder();
for(int i = 0; i < num; i++){
space.append(" ");
}
return space.toString();
}
public String toString(){
StringBuilder res = new StringBuilder();
int floors = (int) Math.floor(Math.log(num)/Math.log(2)) + 1;
for(int i = 1, k = 1; i <= num; i++){
if(Math.pow(2, k-1) == i){
res.append(getSpace(floors - k));
}
res.append(stack[i]);
if(Math.pow(2, k) -1 == i){
k++;
res.append("\n");
}else {
res.append(getSpace(1));
}
}
return res.toString();
}
//stack sort
public void sort(Comparable[] a){
if(a == null)
return;
int n = a.length;
for(int i = n/2 ; i >= 0; i--){
sink(a, i, n);
}
System.out.println(Arrays.toString(a));
int n2 = n -1;
while(n2 > 0){
SelectionSort.exchange(a, 0, n2--);
sink(a, 0, n2 + 1);
}
}
private void sink(Comparable[] a, int k, int n){
int index = k + 1;
while(index*2 -1 < n){
int exeCNode = index*2 - 1;
if( exeCNode + 1 < n && a[exeCNode +1] != null && a[exeCNode] != null && a[exeCNode].compareTo(a[exeCNode +1]) < 0)
exeCNode = exeCNode +1;
if(a[exeCNode].compareTo(a[index - 1]) > 0)
SelectionSort.exchange(a, exeCNode, index - 1);
index = exeCNode;
index++;
}
}
public static void main(String[] args){
CompletedSortedStack<Integer> stack = new CompletedSortedStack<>();
for(int i = 0; i < 20; i++){
stack.insert(i);
}
System.out.println(stack);
stack.deleteMax();
System.out.println(stack);
stack.deleteMax();
System.out.println(stack);
Integer[] a = {6, 2, 3, 4, 9, 11, 15, 16, 1, 6};
System.out.println(Arrays.toString(a));
//Integer[] a = {6, 2, 3};
stack.sort(a);
System.out.println(Arrays.toString(a));
}
}