2.4.22调整数组大小。在MaxPQ中加入调整数组大小的代码,并和命题Q一样证明对于一般性长度为N的队列其数组访问上限。
public class E2d4d22<Key extends Comparable<Key>>
{
private Key[] pq;
private int N=0;
public E2d4d22(int maxN)
{ pq=(Key[]) new Comparable[maxN+1];}
public boolean isEmpty()
{ return N==0;}
public int size()
{ return N;}
public void Insert(Key v)
{
if(N==pq.length-1) resize(2*N);
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-1)/4) resize(2*N);
return max;
}
private void swim(int k)
{
while(k>1 && less(k/2,k))
{
exch(k/2,k);
k=k/2;
}
}//end swim
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;
}
}//end sink
private boolean less(int i,int j)
{ return pq[i].compareTo(pq[j])<0;}
private void exch(int i,int j)
{
Key tmp=pq[i];
pq[i]=pq[j];
pq[j]=tmp;
}
public void show()
{
for(int i=1;i<=N;i++)
StdOut.printf("%s ",pq[i]);
StdOut.println();
}
private void resize(int max)
{
Key[] temp=(Key[]) new Comparable[max+1];
for(int i=1;i<=N+1;i++)
temp[i]=pq[i];
pq=temp;
}
}
1)插入元素最坏情况下因增倍数组长度需要读写数组长度为N,再加swim()方法最多需要访问lg(N+1)次,共计2N+2lg(N+1)次。
2)删除元素最坏情况下因减半数组长度需要读写数组N次,再加个sink()方法最多需要访问lg(N)正比次(两个子节点比较,一个父结点和大子结点比较,一次父结点与大子结点交换),共计2N+6lg(N)次。