* 从0开始的最大堆
* 通过插入排序的思想进行了优化
* 实现了增删改查
/**
* 从0开始的最大堆
* 通过插入排序的思想进行了优化
* 实现了增删改查
* @author 叶叶叶
*
* @param <E>
*/
public class MaxHeap<E extends Comparable<E>>{
private Array<E> data;//data自带了size
public MaxHeap() {
data = new Array<>();
}
public MaxHeap(int capacity){
data = new Array<>(capacity);
}
public int size() {//当前元素的个数
return data.getSize();
}
public boolean isEmpty() {//该最大堆,是否为空
return size()==0;
}
public int parent(int index) {//找到父元素的索引,即下标
if(index == 0)
throw new IllegalArgumentException("index-0 doesn't have parent.");
return (index-1)/2;
}
public int leftChild(int index) {//找左孩子的索引
return 2*index + 1;
}
public int rightChild(int index) {//找右孩子的索引
return 2*index + 2;
}
public void add(E e) {//增加一个元素在最后,然后不停的与父亲比较,再让父亲与父亲的父亲比较
data.addLast(e);
siftUp(size()-1);//传入下标
}
public void remove() {
}
private void siftUp(int index) {
E temp = data.get(index);
while(index>0 && temp.compareTo(data.get(parent(index))) > 0) {
data.set(index, data.get(parent(index)));
index = parent(index);
}
data.set(index, temp);
}
// 看堆中的最大元素
public E findMax(){
if(data.getSize() == 0)
throw new IllegalArgumentException("Can not findMax when heap is empty.");
return data.get(0);
}
// 取出堆中最大元素
public E extractMax() {
E ans = findMax();
data.set(0, data.get(size()-1));
data.removeLast();
siftDown(0);
return ans;
}
public E replace(E e) { // 取出堆中的最大元素,并且替换成元素e
E ans = findMax();
data.set(0, e);
siftDown(0);
return ans;
}
private void siftDown(int index) {
E temp = data.get(index);
while(leftChild(index)<size()) {//右孩子空或者左孩子大的情况下,索引指向左孩子
if(rightChild(index)>=size() || data.get(leftChild(index)).compareTo(data.get(rightChild(index)))>0) {
if(temp.compareTo(data.get(leftChild(index))) > 0)
break;
index = leftChild(index);
}
else {
if(temp.compareTo(data.get(rightChild(index))) > 0)
break;
index = rightChild(index);
}
data.set(parent(index), data.get(index));
}
data.set(index, temp);
}
boolean isMaxHeap() {
return isMaxHeap(0, null);
}
public boolean isMaxHeap(int index,E e) {
if(index >= size())
return true;
return (e==null?true:(data.get(index).compareTo(e)<0)) && isMaxHeap(leftChild(index),data.get(index)) && isMaxHeap(rightChild(index),data.get(index));
}
@Override
public String toString() {
StringBuilder res = new StringBuilder();
res.append(String.format("MaxHeap: size = %d , capacity = %d, isMaxHeap:"+isMaxHeap()+"\n", size(), data.getCapacity()));
res.append('[');
for(int i = 0 ; i < size() ; i ++){
res.append(data.get(i));
if(i != size() - 1)
res.append(", ");
}
res.append(']');
return res.toString();
}
public static void main(String[] args) {
MaxHeap<Integer> heap = new MaxHeap<>();
for(int i=0;i<15;i++) {
heap.add(new Integer((int) (100*Math.random())));
System.out.println(heap);
}
for(int i=0;i<5;i++) {
heap.extractMax();
System.out.println(heap);
}
}
}