* 完全二叉堆的insert findMax deletemax 操作,批量建堆,以二叉树为神,数组为形实现高效的操作,insert ,deletemax操作
* 只需logn的时间,主要花费在上滤后下滤调整上。findMax只需0(1)时间。
* 此处还有要注意到(i-1/2的操作特殊,迭代到最后值为0;边界问题时要注意。
* 详见文件weiTest.java;
* 为方便操作,封装node的封装没有进行。
*/
package BinHeap;
import java.util.ArrayList;
public class BinHeap {
private ArrayList<BinHeapNode> bin = new ArrayList();
public BinHeapNode parent (int i){
return ((i-1)>>1)>=0?bin.get((i-1)>>1):null;
}
public BinHeapNode lchild(int i){
return (i*2+1)<bin.size()?bin.get(i*2+1):null;
}
public BinHeapNode rchild(int i){
return ((i+1)*2)<bin.size()?bin.get((i+1)*2):null;
}
public boolean haschild(int i){
if((i*2+1)< (bin.size()))
return true;
return false;
}
//上滤调整操作
private void updata(int t ){
int i = t;
while(parent(i)!=null){
if(parent(i).data>bin.get(i).data)
break;
BinHeapNode q = parent(i);
bin.set((i-1)>>1, bin.get(i));
bin.set(i, q);
i=(i-1)>>1;//注意边界,最后值为-1,(i-1)/2时。最终值为0,无法跳出循环。
}
}
//下滤调整操作
private void downdata(int t){
int i = t;
while(haschild(i)){
BinHeapNode pt = bin.get(i);
if(pt.data>lchild(i).data&&pt.data>(rchild(i)!=null?rchild(i).data:-1)){
break;}
else{
int j = i;
i = lchild(i).data>(rchild(i)!=null?rchild(i).data:-1)?i*2+1:(i+1)*2;
BinHeapNode st = bin.get(i);
bin.set(i, pt);
bin.set(j, st);
}
}
}
//插入操作
public void insert(int x){
BinHeapNode p = new BinHeapNode(x);
bin.add(p);
updata(bin.size()-1);
}
//取的最大值
public BinHeapNode findmax(){
return bin.get(0);
}
//删除最大值,并返回
public BinHeapNode deletemax(){
BinHeapNode q = bin.get(0);
int t = bin.size()-1;
bin.set(0,bin.get(t));
bin.remove(t);
downdata(0);
return q;
}
//批量建堆
public void compHeap(int[] a,int n){
for(int i = 0;i<n;i++){
BinHeapNode p = new BinHeapNode(a[i]);
bin.add(p);
}
for(int i = n-1; i>-1;i--){
downdata(i);
}
}
public static void main(String[] args){
int[] a = new int[100];
for(int i = 0;i<100;i++){
a[i] = i;
}
BinHeap bh = new BinHeap();
bh.compHeap(a, 100);
System.out.println("....."+bh.findmax().data);
System.out.println("....."+bh.deletemax().data);
System.out.println("....."+bh.deletemax().data);
/*
*
for(int i=0;i<100;i++){
bh.insert(i);
System.out.println("....."+bh.findmax().data);
System.out.println("........................");
}
for(int i =100;i>0;i--){
System.out.println("........................");
System.out.println("....."+bh.deletemax().data);
}
*/
}
}
以下是节点类的实现,新手只提供基本定义
package BinHeap;
public class BinHeapNode {
public int data;
public BinHeapNode(int data){
this.data = data;
}
}
package BinHeap;
public class weiTest {
public int i =10;
public static void main(String[] args){
weiTest wei = new weiTest();
int t1 = 10000;
int t2 = 10000;
int t3= 10000;
int t4 =10000;
int t5 = 10000;
for(int i =0 ;i<50;i++){
t1 = (t1-1)/2; //-1时为特殊情况最后变为0,即始终为非负,其余情况下,会变为负数。
t2=(t2-1)>>1;//迭代次数多了之后,最终变为-1;无上述特殊情况。
t3=(t3<<1)+1;//存在优先级问题,+运算符优先级高于位运算操作符;
t5 =t3<<1 +1;
t4=t4*2+1; //大到一定程度会变为负数
System.out.println(t1+"...."+t2+"...."+t3+"....."+t5+"......"+t4);
}
}
}
1954

被折叠的 条评论
为什么被折叠?



