二叉树应用-堆

本例中实现了最小堆的构造、插入、删除。最小堆表示一个非终端节点均不大于其左右孩子节点。最小堆用完全二叉树表示,但是二叉树存入一维数组中。

将完全二叉树存入数组,有一些性质。先将二叉树从上到下,从左到右给每个节点编号0,1....n。那个一个节点编号i,他的左孩子编号为2*i+1,右孩子编号2*i+2。完全二叉树的最后一个分支节点(非终端节点)为(n-2)/2。

堆的构造:找到最后的分支节点,使用filterDown将它构造成堆。然后在将在该节点前面的子树构造成堆。直到将根节点构造成堆。

....

代码:

public class App 
{
	
	public static void main(String[] arg) {
		int[] array= {80,57,99,35,23,11,74,29,62,16};

		MinHeap minHeap=new MinHeap(array);
		System.out.println(Arrays.toString(minHeap.array));
		minHeap.insert(14);
		System.out.println(Arrays.toString(minHeap.array));
		System.out.println(minHeap.deleteTop());
		System.out.println(Arrays.toString(minHeap.array));
	}
	
	static class MinHeap{
		int currentSize;
		int [] array;
		final static int CAPACITY=30;
		MinHeap(int[] array){
			this.array=new int[CAPACITY];
			for(int i=0;i<array.length;i++) {
				this.array[i]=array[i];
			}
			currentSize=array.length;
			
			int last=(currentSize-2)/2;
			while(last>=0) {
				filterDown(last);
				last--;
			}
		}
		void filterDown(int start) {
			int i=start,j=2*i+1;
			int temp=array[i];
			while(j<currentSize) {
				if(j+1<currentSize && array[j]>array[j+1]) {
					j++;
				}
				if(temp>array[j]) {
					array[i]=array[j];
					i=j;
					j=2*i+1;
				}else {
					break;
				}
			}
			array[i]=temp;
		}
		void insert(int d) {
			if(currentSize==array.length) throw new RuntimeException("head is fulfill");
			array[currentSize]=d;
			filterUp(currentSize);
			currentSize++;
			
		}
		
		void filterUp(int p) {
			int j=p,i=(j-1)/2;
			int temp=array[j];
			while(i>=0) {
				if(temp<array[i]) {
					array[j]=array[i];
					j=i;
					i=(j-1)/2;
				}else {
					break;
				}
			}
			array[j]=temp;
		}
		
		int deleteTop() {
			int temp=array[0];
			array[0]=array[currentSize-1];
			currentSize--;
			filterDown(0);
			return temp;
		}
	}




}

filterUp的流程图:

猜你喜欢

转载自blog.csdn.net/jdbdh/article/details/82153964