堆是一种特殊的数据结构,是一种特殊形式的完全二叉树。
堆分为:(1)大顶堆,大顶堆中每个节点的值都不大于其父节点的值
(2)小顶堆,小顶堆中每个节点的值都不小于其父节点的值
堆分为二项式堆、斐波那契堆、二叉堆(完全二叉堆)。
堆本身就是完全二叉树,可以使用一个一维数组,0位置用来存储元素的个数,1—n用来存储元素。
堆的插入和删除操作的时间复杂度都是O(logn).
二叉堆的实现代码如下:
package com.threetop.www;
/**
* 堆的基本操作
* @author wjgs
*
*/
public class Heap {
private int[]element;
//构造函数实现初始化
public Heap(int maxsize)
{
element=new int[maxsize+1];
element[0]=0;
}
/**
* 判断堆是否为空
*/
public boolean isEmpty()
{
return element[0]==0;
}
/**
* 判断堆是否为满
*/
public boolean isFull()
{
return element[0]==element.length-1;
}
/**
* 向大顶堆中插入一个元素
*/
public void insert(int value)
{
if(isFull())
{
throw new IndexOutOfBoundsException("大顶堆已经满啦!");
}
if(isEmpty())
{
element[1]=value;
}else
{
int i=element[0]+1; //确认新增元素的下标
while(i!=1&&value>element[i/2])
{
//如果比父节点的值大,则父节点的值下降
element[i]=element[i/2];
i/=2;
}
//最终把值插入指定位置
element[i]=value;
}
element[0]++; //堆中的元素加1
}
/**
* 删除大顶堆中的最大元素(删除根元素)
*/
public int delete()
{
if(isEmpty())
{
throw new IndexOutOfBoundsException("大顶堆已经空啦!");
}
//删除元素,先赋值为最后一个有效元素
int deleteElement=element[1];
element[1]=element[element[0]];
element[0]--; //元素的个数减少1个
int temp=element[1];
//重建堆
int parent=1;
int child=2;
//循环至叶子节点
while(child<=element[0])
{
if(child<element[0]&&element[child]<element[child+1])
{
child++;
}
if(temp>element[child])
{
break;
}else
{
element[parent]=element[child];
parent=child;
child*=2;
}
}
//把最后一个有效元素放到该放的位置
element[parent]=temp;
//返回删除的根节点
return deleteElement;
}
/**
* 打印堆内的数据
*/
public void printAll()
{
for(int i=1;i<element[0]+1;i++)
{
System.out.print(element[i]);
if(i!=element[0])
{
System.out.print(",");
}
}
System.out.println();
}
/**
* 堆排序的实现
*
*/
public void sort()
{
if(isEmpty())
{
throw new RuntimeException("先给点初始化数据再来排序");
}
//依次删除元素,放入数组的最后
int size=element[0];
for(int i=0;i<size;i++)
{
int deletElement=delete();
System.out.print(deletElement+" ");
//将要删除的元素的放在数组的末尾
element[element[0]+1]=deletElement;
}
System.out.println();
//输出正序排序后的数组
for(int i=1;i<size+1;i++)
{
System.out.print(element[i]+" ");
}
}
public static void main(String []args)
{
Heap heap=new Heap(100);
heap.insert(9);
heap.insert(18);
heap.insert(34);
heap.insert(15);
heap.insert(29);
heap.insert(66);
heap.insert(12);
heap.insert(48);
//打印堆中所有的数据
heap.printAll();
//删除堆根元素
System.out.println("删除大根堆的根元素为:"+heap.delete());
heap.printAll();
System.out.println("删除大根堆的根元素为:"+heap.delete());
heap.printAll();
}
}