Algs4-2.4.15线性时间内检测pq[]数组是否为最小堆
2.4.15设计一个程序,在线性时间内检测数组pq[]是否是一个面向最小元素的堆。
答:最小元素的堆的特点是所有的非叶子结点都小于等于其直接子结点,换一种说法是除根结点外所有结点都大于等于其父结点。
从数组开始到最后,检查除根结点外的所有结点是否大于等于其父结点,只要出现一个结点不满足要求时返回假,除根结点外的所有结点符合要求时返回真。下面的isMin函数实现这个算法。
public class E2d4d15<Key extends Comparable<Key>>
{
private Key[] pq;
private int N=0;
public E2d4d15(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 delMin()
{
Key min=pq[1];
exch(1,N--);
pq[N+1]=null;
sink(1);
return min;
}
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();
}
public boolean isMin()
{
for(int i=2;i<=1;i++)
if (less(i,i/2)) return false;
return true;
}
public static void main(String[] args)
{
E2d4d15 pq=new E2d4d15(15);
pq.Insert(15);
pq.Insert(14);
pq.Insert(8);
pq.Insert(13);
pq.Insert(11);
pq.Insert(7);
pq.Insert(6);
pq.Insert(12);
pq.Insert(1);
pq.Insert(10);
pq.Insert(9);
pq.Insert(5);
pq.Insert(4);
pq.Insert(3);
pq.Insert(2);
//pq.show();
StdOut.println(pq.isMin());
while(!pq.isEmpty())
StdOut.println(pq.delMin());
}
}
答:最小元素的堆的特点是所有的非叶子结点都小于等于其直接子结点,换一种说法是除根结点外所有结点都大于等于其父结点。
从数组开始到最后,检查除根结点外的所有结点是否大于等于其父结点,只要出现一个结点不满足要求时返回假,除根结点外的所有结点符合要求时返回真。下面的isMin函数实现这个算法。
public class E2d4d15<Key extends Comparable<Key>>
{
private Key[] pq;
private int N=0;
public E2d4d15(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 delMin()
{
Key min=pq[1];
exch(1,N--);
pq[N+1]=null;
sink(1);
return min;
}
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();
}
public boolean isMin()
{
for(int i=2;i<=1;i++)
if (less(i,i/2)) return false;
return true;
}
public static void main(String[] args)
{
E2d4d15 pq=new E2d4d15(15);
pq.Insert(15);
pq.Insert(14);
pq.Insert(8);
pq.Insert(13);
pq.Insert(11);
pq.Insert(7);
pq.Insert(6);
pq.Insert(12);
pq.Insert(1);
pq.Insert(10);
pq.Insert(9);
pq.Insert(5);
pq.Insert(4);
pq.Insert(3);
pq.Insert(2);
//pq.show();
StdOut.println(pq.isMin());
while(!pq.isEmpty())
StdOut.println(pq.delMin());
}
}