数据结构-堆实现

 堆的定义:有如下性质的完全二叉树:任意节点X所处的项的关键字大于或等于以X为根的子数中的所有节点出的项的关键字。

     意义在于,在数据结构中,其常常被用作优先级队列的结构,其意义是每次从队列中获取的元素,总是最满足某个条件的;比如最大的元素;再例如先进先出队列所满足的特定条件就是,具备放入队列时间最早的那个元素。

     堆实现的主要操作就是 插入和 删除(移除并获取那个最符合条件的元素)。先简单描述下逻辑

     插入:1.   将新插入的元素,放置到队列的尾部。

              2.    若该元素大于其父节点,两个元素互换。(上移操作)

              3.    循环第2步,直至该元素没有父节点或小于其父节点。

     删除:1.    移掉顶部的节点。

              2.    将队末的元素放置到顶部。

              3.    该节点与其子节点中较大的那个比较,若小于它,则交换位置,(下移操作)

              4.    循环第3步,直到叶节点或不再比其子节点中较大那个小。

     若是最小堆,比较都反过来。

     在实现的中,用ArrayList作为其内部容器,首先因为ArrayList基于数组,方便快速定位,父节点与子节点的关系只需要计算下就可以得出: 【2*index + 1 】或【 (index -1)/2】, 其次ArrayList以及自动实现了写基础操作,扩容、判空、容器大小等。

public class Heap<T extends Comparable<T>> {
	ArrayList<T> items;
	int cursor; //用于计数
	
	public Heap(int size){
		items = new ArrayList<T>(size);
		cursor = -1;
	}
	
	public Heap(){
		items = new ArrayList<T>();
		cursor = -1;
	}
	/**
	 * 上移操作
	 * @param index 被上移元素的起始位置。
	 */
	void siftUp(int index){
		T intent = items.get(index);
		while(index > 0){
			int pindex = (index - 1)/2;
			T parent = items.get(pindex);
			if(intent.compareTo(parent) > 0){//上移的条件,比父节点大
				items.set(index, parent);
				index = pindex;
			}else break;
		}
		items.set(index, intent);
	}
	/**
	 * 下移操作
	 * @param index 被下移的元素的起始位置
	 */
	void siftDown(int index){
		T intent = items.get(index);
		int l_index = 2*index +1;
		while(l_index < items.size()){
			T maxChild = items.get(l_index);
			int max_index = l_index;
			
			int r_index = l_index + 1;
			if(r_index < items.size()){
				T rightChild = items.get(r_index);
				if(rightChild.compareTo(maxChild) > 0){
					maxChild = rightChild;
					max_index = r_index;
				}
			}
			
			if(maxChild.compareTo(intent) > 0){
				items.set(index, maxChild);
				index = max_index;
				l_index = index * 2 + 1 ;
			}else break;
			
		}
		items.set(index, intent);
	}
	
	public void add (T item){
		//先添加到最后
		items.add(item);
		//循环上移,以完成重构
		siftUp(items.size() -1);
	}
	
	public T deleteTop(){
		if(items.isEmpty()){
			throw new NoSuchElementException();
		}
		//先获取顶部节点
		T maxItem = items.get(0);
		T lastItem = items.remove(items.size() -1 );
		if(items.isEmpty()){
			return lastItem;
		}
		//将尾部的节点放置顶部,下移,完成重构
		items.set(0, lastItem);
		siftDown(0);
		return maxItem;
	}
	
	public T next(){
		if(cursor < 0 || cursor == (items.size() -1)){
			return null;
		}
		cursor++;
		return items.get(cursor);
	}
	
	public T first(){
		if (items.size() == 0 ) return null;
		cursor = 0;
		return items.get(0);
	}
	
	public boolean isEmpty(){
		return items.isEmpty();
	}
	
	public int size(){
		return items.size();
	}
	
	public void clear(){
		items.clear();
	}
}

 转载 

http://my.oschina.net/BreathL/blog/71602

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值