您的位置:首页 > 理论基础 > 数据结构算法

数据结构之堆

2015-09-10 13:13 941 查看
堆同一般二叉树一样可采用顺序存储和链接存储,但是由于堆是一颗完全二叉树,所以适合采用顺序存储,这样才能够充分利用存储空间。

对堆进行顺序存储时,首先要对堆中的所有结点进行编号,然后再以编号为下标存储到指定的数组的对应元素中。为了利用数组的0号元素,让堆中结点的编号从0开始,顺序为从上到下,从左到右,若堆中含有n个结点,则编号的范围为0~n-1。

堆中编号为0~(n/2)-1(n/2向下取整)的结点为分支结点,编号为n/2(向下取整)~n-1的结点为叶子结点;当n为奇数的时候则每个分支结点既有左孩子也有右孩子,当n为偶数的时候则编号为最大分支结点只有左孩子没有右孩子;对于每一个编号为i的分支结点,其左孩子结点的编号为2i+1,右孩子结点的编号为2i+2;除编号为0的结点外,对于其他编号为i的结点,其双亲结点的编号为(i-1)/2(向下取整)。

package org.heap.cn;
/**
 * 堆分为小根堆和大根堆(均为二叉树)
 * 1)若树根节点存在孩子,则根节点的值小于等于左孩子节点的值
 * 2)若树根节点存在右孩子,则根节点的值小于等于右孩子的节点的值
 * 3)以左,右孩子为根的子树又各是一个堆
 * 大根堆的定义与上述差不多,大于等于
 * @author Administrator
 *
 */
public interface HeapADT {

	/**
	 * 向堆中插入一个元素
	 * @param obj
	 */
	void  insert(final Object obj);
	/***
	 * 从堆中删除堆顶元素并返回
	 * @return
	 */
	Object delete();
	/***
	 * 返回堆中元素的个数
	 */
	int size();
	/***
	 * 按照二叉树的广义表格输出一个堆
	 */
	void output();
	/**
	 * 堆是否为空
	 * @return
	 */
	boolean isEmpty();
	/***
	 * 清除一个堆,,使之成为空堆
	 */
	void clear();
	
}
package org.heap.cn;

public class SequenceHeap implements HeapADT {
	final int maxSize=10;
	private Object[] heapArray;
	private int length;  //当前堆的实际长度
	public SequenceHeap() {
		// TODO Auto-generated constructor stub
		length=0;
		heapArray=new Object[maxSize];
	}
	public SequenceHeap(int n){
		if(n<=0){
			System.out.println("数组长度应大于0");
		}
		length=0;
		heapArray=new Object
;
	}
	@Override
	public void insert(Object obj) {
		if(length==heapArray.length){
			Object[] p=new Object[2*length];
			for(int i=0;i<length;i++){
				p[i]=heapArray[i];
			}
			heapArray=p;
		}
		heapArray[length++]=obj;//向数组length的位置上添加新元素
		int i=length-1;  //指向待调整的元素位置,初始指向新元素所在的堆尾
		while(i!=0){
			int j=(i-1)/2;
			if(((Comparable)obj).compareTo((Comparable)heapArray[j])>=0){
				break;  //找到新元素插入位置就退出循环
			}
			heapArray[i]=heapArray[j];   //双亲元素下移
			i=j;
		}
		heapArray[i]=obj;
		
	}

	@Override
	public Object delete() {
		// TODO Auto-generated method stub
		if(length==0){
			System.out.println("当前的堆为空,不能删除");
			return null;
		}
		Object temp=heapArray[0];  //temp为堆顶元素
		length--;
		if(length==0){
			return temp;
		}
		Object x=heapArray[length];
		int i=0;
		int j=1;
		while(j<=length-1){
			if(j<length-1 && ((Comparable)heapArray[j]).compareTo(heapArray[j+1])>0){
				j++;
			}
			if(((Comparable)heapArray[j]).compareTo(heapArray[j+1])<=0){
				break;
			}
			heapArray[i]=heapArray[j];
			i=j;
			j=2*i+1;
		}
		heapArray[i]=x;
		return temp;
	}

	@Override
	public int size() {
		// TODO Auto-generated method stub
		return 0;
	}

	@Override
	public void output() {
		// TODO Auto-generated method stub
		outPut(0);
		System.out.println();
	}
	private void outPut(int rt){
		if(rt<length){
			System.out.println(heapArray[rt]);
			if(2*rt+1<length){
				System.out.println('(');
				outPut(2*rt+1);
				if(2*rt+2<length){
					System.out.println(',');
				}
				outPut(2*rt+2);
				System.out.println(')');
			}
		}
	}

	@Override
	public boolean isEmpty() {
		// TODO Auto-generated method stub
		return length==0;
	}

	@Override
	public void clear() {
		// TODO Auto-generated method stub
		length=0;
	}

	
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: