数据结构之堆

堆实际也是一种二叉数。特点是父节点的数值总是大于等于子节点的数值。堆可以用来实现堆排序,也可以用来实现优先队列。


//堆实现为泛型类,实现类型必须实现Comparable接口

public class Heap <T extends Comparable>{
	private List<T> data;   //数据放在list里面
	
	public Heap(){
		data=new ArrayList<T>();
	}
	
	public boolean isEmpty(){
		return data.isEmpty();
	}
	
	public int Size(){
		return data.size();
	}
	
	//添加新元素,策略:先添加到list末尾,然后和父节点比,如果比父节点大,则换位,如此递归下去。
	public void add(T t){
		data.add(t);
		int currentIndex=data.size()-1;
		while(currentIndex>0){
		
			int p_index=(currentIndex+1)/2-1;
			int res=data.get(p_index).compareTo(data.get(currentIndex));
			if(res<0){
				T temp=data.get(currentIndex);
				data.set(currentIndex, data.get(p_index));
				data.set(p_index, temp);
				currentIndex=p_index;
			}else{
				break;
			}
		}	
	}
	

	/*
	删除元素,策略:每次都拿list最后的一个数值覆盖第一个数值,list长度减1,然后比较第一个元素和两个孩子(可能没有或者有一个或者两个孩子),如果
	孩子的值更大,则互换值,如此递归
	*/
	public T remove(){
		if(data.size()==0) throw new NullPointerException();
		T result=data.get(0);
		data.set(0, data.get(data.size()-1));
		data.remove(data.size()-1);
		if(data.size()==0)
			return result;
		
		int curIndex=0;
		while(curIndex<data.size()-1){
		//	System.out.println("currentIndex="+curIndex);
			int left_index=curIndex*2+1;
			int right_index=curIndex*2+2;
			if(data.size()-1<left_index) //如何已经没有孩子
				break;
			     if(left_index==data.size()-1){   //只有左子树
			    	  int res=data.get(left_index).compareTo(data.get(curIndex));
			    	  if(res>0){
			    		  T temp=data.get(left_index);
			    		  data.set(left_index, data.get(curIndex));
			    		  data.set(curIndex, temp);
			    		  break;
			    	  }else{
			    		  break;
			    	  }
			     }else{
			    	  T cur_data=data.get(curIndex);
			    	  T left_data=data.get(left_index);
			    	  T right_data=data.get(right_index);
			    	  if(cur_data.compareTo(left_data)>=0&&cur_data.compareTo(right_data)>=0)
			    		  break;
			    	 int res=left_data.compareTo(right_data);
			    	 if(res>0){
			    		  data.set(left_index, cur_data);
			    		  data.set(curIndex, left_data);
			    		  curIndex=left_index;
			    		  continue;
			    	 }else{
			    		  data.set(right_index, cur_data);
			    		  data.set(curIndex, right_data);
			    		  curIndex=right_index;
			    		  continue;
			    	 }
			    	  
			     }		     
		}
		return result;		
	}
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值