package maxheap;
import java.util.ArrayList;
import java.util.List;
public class Test1 {
static class MaxHeap{
ArrayList<Integer> data;
public MaxHeap(){
data=new ArrayList<Integer>();
}
public int parent(int index){
if (index<0){
throw new RuntimeException("无父节点");
}
return (index-1)/2;
}
public void swap(int index,int parent){
int temp=data.get(parent);
data.set(parent,data.get(index));
data.set(index,temp);
}
public int leftNode(int index){
int leftNode= 2*index+1;
return leftNode;
}
public int rightNode(int index){
int rightNode=2*index+2;
return rightNode;
}
public void siftUp(int index){
while (data.get(index)>data.get(parent(index))&&index>0){
swap(index,parent(index));
index=parent(index);
}
}
public void siftDown(int index){
//如果大于data的存在数的长度,就代表越界了
while (leftNode(index)<data.size()){
//j在这里的含义是父和左右节点中最大数的下标
int j=leftNode(index);
//判断左右节点的大小,把j赋值上
if (j+1<data.size()&&data.get(j)<data.get(j+1)){
j=rightNode(index);
}
if (data.get(index)>data.get(j)){
break;
}
swap(index,j);
index=j;
}
}
public void add(int value){
data.add(value);
if (data.size()>0){
siftUp(data.size()-1);
}
}
//替换根节点的数据,有直接替换和 先删除后替换,明显直接替换比较换
public void replace(int value){
if (data.size()>0){
data.set(0,value);
siftDown(0);
}
}
//将任意的数组转化成堆
public void heapify(ArrayList<Integer> list){
data=list;
//找到第一个有子节点的树,就是parent(data.size() - 1)
//然后依次向左遍历
for (int i = parent(data.size() - 1);i>=0 ;i--) {
siftDown(i);
}
}
public int findMax(){
if (data.size()<=0){
throw new RuntimeException("数组越界");
}
return data.get(0);
}
public int extractMax(){
int max = findMax();
data.set(0,data.get(data.size()-1));
data.remove(data.size()-1);
if (data.size()>0)
siftDown(0);
return max;
}
}
public static void main(String[] args) {
List<Integer> a=new ArrayList<Integer>();
a.add(2);
a.add(3);
a.add(-1);
a.add(20);
a.add(800);
a.add(55);
a.add(66);
a.add(49);
MaxHeap maxHeap=new MaxHeap();
maxHeap.heapify((ArrayList<Integer>)a);
int in=maxHeap.data.size();
for (int i = 0; i <in ; i++) {
System.out.println(maxHeap.extractMax());
}
// MaxHeap maxHeap=new MaxHeap();
// maxHeap.add(1);
// maxHeap.add(2);
// maxHeap.add(3);
// maxHeap.add(4);
// maxHeap.add(30);
// maxHeap.add(40);
// maxHeap.add(80);
// maxHeap.add(46);
// maxHeap.add(-1);
// maxHeap.replace(20);
// int in=maxHeap.data.size();
// for (int i = 0; i <in ; i++) {
// System.out.println(maxHeap.extractMax());
// }
}
}
堆头可以是最大或者最小值,堆并没有二叉树的性质(即左边节点小于父节点,右边节点大于父节点)
而二叉堆的性质是父节点一定大于子节点,是一个完全二叉树,用数组实现
优先队列可以用堆进行实现,方法基本相同,只是用队列的形式进行再封装。