/**
* 数据结构:最大堆(基于【我自定义的】链表)
* 描述:实现了 添加、删除、判空、判断、上浮、下沉、是否存在
* @author hcc
*
*/
public class ArrayHeap<E extends Comparable<E>> {
private HLinkList<E> array;
public ArrayHeap() {
array = new HLinkList<E>();
}
/**
* 向堆中添加元素【先添加元素,在上浮到指定位置】
* @param e
*/
public void add(E e) {
array.add(e);
goUp();
}
/**
* 上浮操作
*/
private void goUp() {
int index = array.getSize() - 1;
int parentIndex = getParentIndex(index);
while (true) {
if (array.get(index).compareTo(array.get(parentIndex)) > 0) {
swap(index, parentIndex);
index = parentIndex;
parentIndex = getParentIndex(parentIndex);
} else {
break;
}
}
}
/**
* 数据交换操作
* @param index 子节点的索引值
* @param parentIndex 父节点的索引值
*/
private void swap(int index,int parentIndex) {
int size = array.getSize();
if(index > (size-1) || parentIndex > (size-1)) {
throw new IllegalArgumentException("索引值错误!");
}
E temporary = array.get(index);
array.set(index, array.get(parentIndex));
array.set(parentIndex, temporary);
}
/**
* 通过index节点的索引获取父节点的索引
* @param index
* @return 父节点的索引
*/
private int getParentIndex(int index) {
if(index < 0) {
throw new IllegalArgumentException("索引的值小于0!");
}
return (index-1)/2;
}
/**
* 通过index节点的索引获取左子节点的索引
* @param index
* @return
*/
private int getLeftIndex(int index) {
if(index < 0) {
throw new IllegalArgumentException("索引的值小于0!");
}
return (2*index+1);
}
/**
* 通过index节点的索引获取有子节点的索引
* @param index
* @return
*/
private int getRightIndex(int index) {
if(index < 0) {
throw new IllegalArgumentException("索引的值小于0!");
}
return (2*index+2);
}
/**
*
* @return 返回堆中最大的数据
*/
public E findMax() {
if(array.getSize() == 0) {
throw new IllegalArgumentException("堆中无数据!!!");
}
return array.get(0);
}
/**
* 从堆中取出最大数【取出后堆的排列顺序发生变化,需要在删除后的堆中再找到最大数】
*/
public E getMax() {
E e = findMax();
swap(0,array.getSize()-1);
array.remove(array.getSize()-1);
moveDown(0);
return e;
}
/**
* 下移操作
* @param index
*/
private void moveDown(int index) {
if(index < 0) {
throw new IllegalArgumentException("索引的值小于0!");
}
while(getLeftIndex(index) < array.getSize()) {
int i = 0;
E e = array.get(index);
int childLeft = getLeftIndex(index);
int childRight = getRightIndex(index);
E childLeftData = array.get(childLeft);
i = childLeft;
if(childRight < array.getSize() && array.get(childRight).compareTo(childLeftData) >= 0) {
i = childRight;
}
if(e.compareTo(array.get(i)) >= 0) {
break;
}
swap(index,i);
index = i;
}
}
/**
*
* @return 数据数量
*/
public int getSize() {
return array.getSize();
}
/**
*
* @param e
* @return true表示堆中存在 false表示堆中不存在
*/
public boolean contain(E e) {
return array.contains(e);
}
/**
*
* @return true表示为空 false表示不为空
*/
public boolean isEmpty() {
return array.isEmpty();
}
public String toString() {
return array.toString();
}
}
网友评论