堆
1.堆的表示
使用数组保存二叉树结构,将二叉树用层序遍历方式放入数组中
(一般只适合完全二叉树,因为非完全二叉树会造成空间浪费)
2.下标对应关系
child1 = parent2+1(左孩子)
child2 = parent2+2(右孩子)
parent = (child-1)/2(不分左右孩子)
堆(heap)的概念
堆逻辑上是一棵完全二叉树
堆物理上是存在数组中的
满足任意节点的值大于其子树中节点的值,叫做大堆,或大根堆,或最大堆
反之,就是小根堆,或最小堆
向下调整
public static void shiftDown(int[]array ,int size,int parent){
int child1 = parent*2+1;//左孩子的下标
while (child1<size){
int tem = child1;
int child2 = parent*2+2;//右孩子的下标
if (child2<size&&array[child1] <array[child2]){//在确定最大孩子前提要满足右孩子在树中,否则会造成下标越界
tem = child2;
}
if (array[parent]>=array[tem]){
break;
}
int num = array[parent];
array[parent] = array[tem];//父亲节点的值和最大的孩子节点交换
array[tem] = num;
parent = tem;
child1 =parent*2+1;
}
}
public static void createHeap(int []array,int size){
for (int i =(size-1-1)/2;i>=0;i--){//遍历所有的父亲节点
shiftDown(array,size,i);
}
}
public static void main(String[] args) {
int[] array = { 15,18,19,25,28,34,65,49,27,37 };
System.out.println(Arrays.toString(array));
createHeap(array,array.length);
System.out.println(Arrays.toString(array));
}
入队
public static void shiftUp(int[]array,int index){//加入的元素下标与其父亲节点进行比较
while (index>0){
int parent = (index-1)/2;
if (array[parent]>=array[index]){
break;
}
int tem = array[parent];
array[parent] =array[index];
array[index] =tem;
index =parent;
}
}
boolean isFoll(int[] array,int size){//判断是否还能再放元素
if (array.length == size){
return true;
}
return false;
}
public void push(int[]arr ,int size, int date){//将元素尾插法插入堆中
if (isFoll(arr,size)){
arr = Arrays.copyOf(arr,arr.length*2);
}
arr[size] = date;
size++;
shiftUp(arr,size);
}
JAVA中的优先级队列
public void priority(int[]array){
PriorityQueue<Integer>priorityQueue = new PriorityQueue<>(new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return o1-o2;
}
});//建小堆
for (int i = 0;i<array.length;i++){
priorityQueue.offer(array[i]);//入队列
}
System.out.println(priorityQueue);
System.out.println(priorityQueue.peek());//打印堆首元素
priorityQueue.poll();//出堆首元素
System.out.println(priorityQueue);
PriorityQueue<Integer>priorityQueue1 = new PriorityQueue<>(new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return o2-o1;
}
});//建大堆
while (!priorityQueue.isEmpty()){//将priorityQueue的元素依次放入priorityQueue1中,建立大堆
priorityQueue1.offer(priorityQueue.poll());
}
System.out.println(priorityQueue1);
}
public static void main(String[] args) {
int[] array = { 15,18,19,25,28,34,65,49,27,37 };
Solution solution = new Solution();
solution.priority(array);
}