优先队列初步实现
p202 加深理解
import java.util.Random;
public class MaxPQ<Key extends Comparable<Key>> {
private Key[] pq;
private int N = 0;
public int getMaxSize(){
return pq.length-1;
}
public MaxPQ(int maxN){
pq = (Key[])new Comparable[maxN+1];
}
public boolean isEmpty(){
return N==0;
}
public boolean isFull(){ return N+1==pq.length; }
public int size(){
return N;
}
public void insert(Key v){
if(isFull()){
Key[] tp = (Key[])new Comparable[2*N+1];
for(int i = 0;i<pq.length;i++){
tp[i]=pq[i];
}
pq = tp;
}
pq[++N] = v;
//上浮
swim(N);
}
public Key delMax(){
Key max = pq[1];
//交换最后一个结点
exch(1,N--);
//防止对象游离
pq[N+1]=null;
//恢复有序(下沉)
sink(1);
if(N<pq.length/2){
Key[] tp = (Key[])new Comparable[pq.length/2];
for(int i = 0;i<tp.length;i++){
tp[i]=pq[i];
}
pq = tp;
}
return max;
}
public void printAll() {
System.out.print("[ ");
for (int i = 1; i < pq.length; i++) {
if(pq[i]!=null)
System.out.print(pq[i] + " ");
}
System.out.println("]");
}
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;
}
//上浮
private void swim(int k){
while(k>1&&less(k/2,k)){
exch(k/2,k);
k/=2;
}
}
//下沉
private void sink(int k){
while(k*2<=N){
int j = k*2;
if(j<N&&less(j,j+1))
j++;
if(less(j,k)) break;
exch(j,k);
k = j;
}
}
public static void main(String[]args){
MaxPQ<Integer> qu = new MaxPQ<>(16);
Random rand = new Random(47);
for(int i = 0;i<30;i++){
qu.insert(rand.nextInt(100));
}
qu.printAll();
System.out.println("数据个数:"+qu.size());
System.out.println("容量:"+qu.getMaxSize());
for(int i = 0;i<16;i++){
qu.delMax();
}
qu.printAll();
System.out.println("数据个数:"+qu.size());
System.out.println("容量:"+qu.getMaxSize());
}
}
堆排序如下
class Sort4 {
/*堆排序*/
public static void sort(int[] pq) {
int N = pq.length-1;
for (int k = N / 2; k >= 1; k--)
sink(pq, k, N);
while (N > 1) {
exch(pq, 1, N--);
sink(pq, 1, N);
}
}
private static boolean less(int[] pq, int i, int j) {
return pq[i]<pq[j];
}
private static void exch(int[] pq, int i, int j) {
int t = pq[i];
pq[i] = pq[j];
pq[j] = t;
}
//下沉
private static void sink(int[] pq, int k, int N) {
while (k * 2 <= N) {
int j = k * 2;
if (j < N && less(pq, j, j + 1))
j++;
if (less(pq, j, k)) break;
exch(pq, j, k);
k = j;
}
}
}
测试
public class MySort {
public static void main(String[] args){
int[]a =new int[1000000];
Random r = new Random(47);
for(int i = 1;i<a.length;i++){
a[i] =r.nextInt(10000000);
}
Stopwatch timer = new Stopwatch();
Sort4.sort(a);//堆排序, 时间0.138ms(数组的0位置没有排序,所以数组从1开始存值)
System.out.println(timer.elapsedTime());
/*输出结果*/
// int i = 0;
// for(int n:a){
// System.out.print(n+" ");
// i++;
// if(i%5==0)
// System.out.println();
// }
}
}
堆排序的索引从1开始,后续需要改进使之更灵活
(未完待续)