父节点下标(x-1)/2

左子节点x*2+1;

右子节点x*2+2

堆的一个结点

public class Node {
	private int iData;
	
	public Node(int key)
	{
		iData=key;
	}
	public void setKey(int id)
	{
		iData=id;
	}
	public int getKey()
	{
		return iData;
	}
	
} 

构建一个堆

public class Heap {
	private Node[] heapArray;//存储节点
	private int maxSize;//最大容量
	private int currentSize;//当前大小
	
	public Heap(int max)
	{
		maxSize=max;
		currentSize=0;
		heapArray=new Node[maxSize];
		
	}
	
	public boolean isEmpty()
	{
		return currentSize==0;
	}
	/**
	 * 插入一个结点
	 * 先插到数组末尾
	 * 从后往前筛选数组使之符合堆的规则
	 * @param key
	 * @return
	 */
	public boolean insert(int key)
	{
		if(currentSize==maxSize)
		{
			return false;
		}
		Node node = new Node(key);
		heapArray[currentSize]=node;//添加到数组末尾
		trickleUp(currentSize++);//从后往前筛选数组使之符合堆的规则 完成后堆的大小+1
		return true;
	}
	
	/**
	 * 判断父节点是否大于当前节点如果大于则筛选完毕如果不大于则 父节点复制到当前节点 当前指针移动到父节点的下标
	 * @param index
	 */
	private void trickleUp(int index) {
		Node temp=heapArray[index];//要替这个节点找到合适的位置
		int parent=(index-1)/2;//父节点
		while(parent>=0&&heapArray[parent].getKey()<temp.getKey())//判断当前节点是否大于父节点如果大于则找到目标位置
		{
			heapArray[index]=heapArray[parent];
			index=parent;
			parent=(parent-1)/2;
		}
		heapArray[index]=temp;//移动到符号的位置
		
	}
	/**
	 * 移除最大节点
	 * @return
	 */
	public Node remove()
	{
		Node root =heapArray[0];
		heapArray[0]=heapArray[--currentSize];//将最后一个节点移动到第一个
		trickleDown(0);//替这个节点找到合适的位置
		return root;
	}

	private void trickleDown(int index) 
	{
		Node temp =heapArray[index];
		
		int largechild;
		while(index<currentSize/2)
		{
			///找到当前节点的较大字节点//
			int  left=index*2+1;
			int right=index*2+2;
			if(right<currentSize&&heapArray[left].getKey()<heapArray[right].getKey())
			{
				largechild=right;
			}
			else
			{
				largechild=left;
			}
		/
			if(temp.getKey()>heapArray[largechild].getKey())//如果当前节点比任意一个子节点大则找到符合他的位置
			{
				break;
			}
			heapArray[index]=heapArray[largechild];
			index=largechild;
		}
		
		heapArray[index]=temp;
	}
	
	
}

对堆原理的介绍比较简略因为我自觉无法讲的清楚明白原理详情参考:Java数据结构与算法 第12章

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值