Heap 堆

Heap 堆 

Heap 堆是 Priority Queue 的一种。Max Heap的parent节点是子树最大的,root是最大值。 Min Heap的parent节点是子树最小的,root是最小值。左右child没有顺序。

定义父类:

public abstract class Heap<T extends Comparable<T>> implements Iterable<T> {
	/**
	 * Max Heap
	 */
	public static boolean MAXHEAP = true;
	
	/**
	 * Min Heap
	 */
	public static boolean MINHEAP = false;
	
	protected boolean order;
	
	protected Comparator<T> comparator;

	/**
	 * Add item to heap
	 * 
	 * @param item
	 *            Item to be added
	 * @return true
	 */
	public abstract boolean add(T item);

	/**
	 * Get and remove the top in the heap
	 * 
	 * @return Top item in the heap
	 */
	public abstract T poll();

	/**
	 * Get the top in the heap
	 * 
	 * @return Top item in the heap
	 */
	public abstract T peek();

	/**
	 * Remove the first occurrence of item
	 * 
	 * @param item
	 *            Item to be removed
	 * @return True if item is removed. False if item doesn't exist.
	 */
	public abstract boolean remove(T item);

	/**
	 * Check if item exists in the heap.
	 * 
	 * @param item
	 *            Item to be checked.
	 * @return True if item exists. False otherwise.
	 */
	public abstract boolean contains(T item);

	/**
	 * Check if the heap is empty.
	 * 
	 * @return True if empty. False otherwise.
	 */
	public abstract boolean isEmpty();

	/**
	 * Return the size of the heap.
	 * 
	 * @return Size of the heap.
	 */
	public abstract int size();

	/**
	 * Percolate Up
	 * 
	 * @param k
	 *            Index
	 */
	protected abstract void percolateUp(int k);

	/**
	 * Percolate Down
	 * 
	 * @param k
	 *            Index
	 */
	protected abstract void percolateDown(int k);

	/**
	 * Compare two items. Use natural order if comparator is not specified.
	 * 
	 * @param a
	 *            Item to be compared
	 * @param b
	 *            Item to be compared
	 * @return In max heap, check a < b. In min heap, check a > b.
	 */
	protected boolean compare(T a, T b) {
		if (comparator != null) {
			int cmp = comparator.compare(a, b);
			if (order == MAXHEAP) {
				return cmp < 0;
			} else {
				return cmp > 0;
			}
		} else {
			if (order == MAXHEAP) {
				return a.compareTo(b) < 0;
			} else {
				return a.compareTo(b) > 0;
			}
		}
	}

	/**
	 * Swap two items in the heap.
	 * 
	 * @param i
	 *            Index of item.
	 * @param j
	 *            Index of item.
	 */
	protected abstract void swap(int i, int j);

}
注意:堆中的元素必须是Comparable的。

数组实现:

public class ArrayHeap<T extends Comparable<T>> extends Heap<T> {
	private T[] heap;
	private int tail = -1;

	/********* Constructors of Array Heap ********/
	@SuppressWarnings("unchecked")
	public ArrayHeap(int capacity, boolean order) {
		heap = (T[]) new Comparable[capacity + 1];
		this.order = order;
	}

	public ArrayHeap(int capacity, boolean order, Comparator<T> comparator) {
		this(capacity, order);
		this.comparator = comparator;
	}

	@SuppressWarnings("unchecked")
	public ArrayHeap(boolean order) {
		heap = (T[]) new Comparable[1 + 1];
		this.order = order;
	}

	public ArrayHeap(boolean order, Comparator<T> comparator) {
		this(order);
		this.comparator = comparator;
	}

	public ArrayHeap(T[] array, boolean order) {
		heap = array.clone();
		tail = heap.length - 1;
		this.order = order;
		for (int k = heap.length / 2 - 1; k >= 0; k--) {
			percolateDown(k);
		}
	}

	public ArrayHeap(T[] array, boolean order, Comparator<T> comparator) {
		heap = array.clone();
		tail = heap.length - 1;
		this.order = order;
		this.comparator = comparator;
		for (int k = heap.length / 2 - 1; k >= 0; k--) {
			percolateDown(k);
		}
	}

	/************* Heap Method *************/
	@Override
	public boolean isEmpty() {
		return tail == -1;
	}

	@Override
	public int size() {
		return tail + 1;
	}

	@Override
	public boolean add(T item) {
		if (tail + 1 == heap.length) {
			resize(heap.length << 1);
		}
		heap[++tail] = item;
		percolateUp(tail);
		return true;
	}

	@Override
	public T poll() {
		if (isEmpty()) {
			return null;
		}
		T top = heap[0];
		swap(0, tail);
		heap[tail--] = null;
		percolateDown(0);
		if (tail + 1 == (heap.length >> 2)) {
			resize(heap.length >> 1);
		}
		return top;
	}

	@Override
	public T peek() {
		return heap[0];
	}

	@Override
	public boolean remove(T item) {
		for (int i = 0; i <= tail; i++) {
			if (heap[i].equals(item)) {
				swap(i, tail);
				heap[tail--] = null;
				percolateUp(i);percolateDown(i);
				return true;
			}
		}
		return false;
	}

	@Override
	public boolean contains(T item) {
		for (int i = 0; i <= tail; i++) {
			if (heap[i].equals(item)) {
				return true;
			}
		}
		return false;
	}

	@Override
	protected void percolateUp(int k) {
		while (k > 0 && compare(heap[(k - 1) >> 1], heap[k])) {
			swap((k - 1) >> 1, k);
			k = (k - 1) >> 1;
		}
	}

	@Override
	protected void percolateDown(int k) {
		while ((k << 1) + 1 <= tail) {
			int child = (k << 1) + 1; // left child
			// Compare left child and right child
			if (child + 1 <= tail && compare(heap[child], heap[child + 1])) {
				++child; // right child
			}
			if (compare(heap[k], heap[child])) {
				swap(k, child);
				k = child;
			} else {
				break;
			}
		}
	}

	@Override
	protected void swap(int i, int j) {
		T temp = heap[i];
		heap[i] = heap[j];
		heap[j] = temp;
	}

	private void resize(int capacity) {
		T[] newheap = (T[]) new Comparable[capacity];
		System.arraycopy(heap, 0, newheap, 0, tail + 1);
		heap = newheap;
	}

	@Override
	protected ArrayHeap<T> clone() {
		ArrayHeap<T> temp = new ArrayHeap<T>(order);
		temp.heap = heap.clone();
		temp.tail = tail;
		temp.comparator = comparator;
		return temp;
	}

	@Override
	public String toString() {
		StringBuilder sb = new StringBuilder();
		for (T i : heap) {
			sb.append(i + " ");
		}
		sb.deleteCharAt(sb.length() - 1);
		return sb.toString();
	}

	@Override
	public Iterator<T> iterator() {
		return new Iterator<T>() {
			ArrayHeap<T> temp = ArrayHeap.this.clone();

			@Override
			public boolean hasNext() {
				return !temp.isEmpty();
			}

			@Override
			public T next() {
				return temp.poll();
			}
		};
	}
}
注意:

1. percolateUp 和 percolateDown是核心操作。

2.  数组自动resize。

3. Iterate按poll的顺序。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值