二叉堆:是被完全填满的二叉树,唯一的例外是在最底层。
二叉堆的应用范围:最优队列(最小堆)、堆排序(最大堆)
内部需要用到的数据结构为数组,并且为了方便处理,一般从数组下标index=1开始填充。
需要有以下几个方法:
1. insertNode往最大堆插入一个节点
2.deleteMax删除最大堆中最大的元素并返回
3.build_max_heap根据一个无序数组构造一个最大堆
4.heapSort()
基本类结构如下代码:
public class MaxHeap<AnyType extends Comparable<? super AnyType>> {
private int currentSize=0; //当前二叉堆中的元素个数
private final static int DEFAULT_SIZE=10; //数组默认的大小
private AnyType[] array;//从数组下标index=1开始保存堆的值
public MaxHeap()
{
array = (AnyType[]) new Comparable[DEFAULT_SIZE];
}
public MaxHeap(int capacity)
{
array = (AnyType[]) new Comparable[capacity+1];
}
public MaxHeap(AnyType[]items)
{
if(items==null)
{
System.out.println("arrsy items is empty");
return;
}
this.array=(AnyType[]) new Comparable[items.length+1];
for(int index=0;index<items.length;index++)
{
array[index+1] = items[index];
}
}
}
public void build_max_heap()
{
build_max_heap(array);
}
private void build_max_heap(AnyType []outArray)
{
for(int index=1;index<outArray.length;index++)
{
insertNode(outArray[index]);
}
}
public void insertNode(AnyType node)
{
if(++currentSize>=array.length)
{
System.out.println("数组array的下标currentSize:"+currentSize+"长度越界");
return;
}
array[currentSize] = node;
int indexFlag = currentSize;
while(indexFlag!=1)
{
if(array[indexFlag/2].
compareTo(array[indexFlag])<0)
{
swap(indexFlag, indexFlag/2);
}
indexFlag = indexFlag/2;
}
}
/**
<span style="white-space:pre"> </span> * 交换数组array两个不同下标的值
<span style="white-space:pre"> </span> * @param index1
<span style="white-space:pre"> </span> * @param index2
<span style="white-space:pre"> </span> */
<span style="white-space:pre"> </span>private void swap(int index1,int index2)
<span style="white-space:pre"> </span>{
<span style="white-space:pre"> </span>AnyType tmp = array[index1];
<span style="white-space:pre"> </span>array[index1] = array[index2];
<span style="white-space:pre"> </span>array[index2] = tmp;
<span style="white-space:pre"> </span>}
deleteMax:
/**
* 删除最大的节点
* @return
*/
public AnyType deleteMax()
{
if (this.currentSize<1) {
System.out.println("空二叉堆,无法执行deleteMax操作");
return null;
}
/**
* 确保删除最大节点后,还满足二叉堆的结构性
* */
swap(1, currentSize);
currentSize--;
this.makeSureOrder(1);
return array[currentSize+1];
}
/**
* 当二叉堆的跟节点失去堆序性时,
* 通过此方法保证二叉堆的堆序性
*/
public void makeSureOrder(int indexFlag)
{
AnyType tmp = array[indexFlag];
int child;
/**
* 只要indexFlag还有子节点,则需要继续遍历
*/
while(2*indexFlag<=currentSize)
{
/**
* 找到indexFlag的第一个子节点
*/
child = 2*indexFlag;
/**
* 如果存在右子节点,并且右子节点大于左子节点,
* 则child右移
*/
if(2*indexFlag<currentSize&&array[child+1].compareTo(array[child])>0)
{
child++;
}
if(array[child].compareTo(tmp)>0)
{
array[indexFlag] = array[child];
indexFlag = child;
}
else {
break;
}
}
array[indexFlag] = tmp;
}
heapSort:
/**
* 对数组堆排序
*/
public void heapSort(AnyType[] outArray)
{
this.build_max_heap();
if(this.currentSize<1)
{
System.out.println("空二叉堆");
return;
}
int length = currentSize;
for(int index=1;index<=length;index++)
{
deleteMax();
}
/**
* 对数组从小到大排序后的结果:
*/
System.out.println("对数组从小到大排序后的结果:");
for(int index=1;index<=length;index++)
{
System.out.println(array[index]);
}
}