最大堆是一个完整的二叉树,其中每个内部节点中的值大于或等于该节点的子节点中的值。
将堆的元素映射到数组是微不足道的:如果节点存储索引 k,则其左子节点存储在索引 2k+1 处,右子节点存储在索引 2k+2 处。
最大堆示例:
最大堆是如何表示的?
A-Max 堆是一棵完全二叉树。 A-Max 堆通常表示为一个数组。根元素将位于 Arr[0]。下表显示了第 i 个节点的其他节点的索引,即 Arr[i]:
Arr[(i-1)/2] 返回父节点。
Arr[(2*i)+1] 返回左子节点。
Arr[(2*i)+2] 返回右子节点。
最大堆上的操作:
1) getMax():返回Max Heap的根元素。此操作的时间复杂度为 O(1)。
2) extractMax():从MaxHeap中取出最大元素。此操作的时间复杂度为 O(Log n),因为此操作需要在移除根后维护堆属性(通过调用 heapify())。
3) insert():插入一个新的key需要O(Log n)的时间。我们在树的末尾添加一个新键。如果新键小于它的父键,那么我们不需要做任何事情。否则,我们需要向上遍历以修复违反的堆属性。
注意:在下面的实现中,我们从索引 1 开始索引以简化实现。
Java
// Java program to implement Max Heap
public class MaxHeap {
private int[] Heap;
private int size;
private int maxsize;
// Constructor to initialize an
// empty max heap with given maximum
// capacity.
public MaxHeap(int maxsize)
{
this.maxsize = maxsize;
this.size = 0;
Heap = new int[this.maxsize + 1];
Heap[0] = Integer.MAX_VALUE;
}
// Returns position of parent
private int parent(int pos) { return pos / 2; }
// Below two functions return left and
// right children.
private int leftChild(int pos) { return (2 * pos); }
private int rightChild(int pos)
{
return (2 * pos) + 1;
}
// Returns true of given node is leaf
private boolean isLeaf(int pos)
{
if (pos > (size / 2) && pos <= size) {
return true;
}
return false;
}
private void swap(int fpos, int spos)
{
int tmp;
tmp = Heap[fpos];
Heap[fpos] = Heap[spos];
Heap[spos] = tmp;
}
// A recursive function to max heapify the given
// subtree. This function assumes that the left and
// right subtrees are already heapified, we only need
// to fix the root.
private void maxHeapify(int pos)
{
if (isLeaf(pos))
return;
if (Heap[pos] < Heap[leftChild(pos)]
|| Heap[pos] < Heap[rightChild(pos)]) {
if (Heap[leftChild(pos)]
> Heap[rightChild(pos)]) {
swap(pos, leftChild(pos));
maxHeapify(leftChild(pos));
}
else {
swap(pos, rightChild(pos));
maxHeapify(rightChild(pos));
}
}
}
// Inserts a new element to max heap
public void insert(int element)
{
Heap[++size] = element;
// Traverse up and fix violated property
int current = size;
while (Heap[current] > Heap[parent(current)]) {
swap(current, parent(current));
current = parent(current);
}
}
public void print()
{
for (int i = 1; i <= size / 2; i++) {
System.out.print(
" PARENT : " + Heap[i]
+ " LEFT CHILD : " + Heap[2 * i]
+ " RIGHT CHILD :" + Heap[2 * i + 1]);
System.out.println();
}
}
// Remove an element from max heap
public int extractMax()
{
int popped = Heap[1];
Heap[1] = Heap[size--];
maxHeapify(1);
return popped;
}
public static void main(String[] arg)
{
System.out.println("The Max Heap is ");
MaxHeap maxHeap = new MaxHeap(15);
maxHeap.insert(5);
maxHeap.insert(3);
maxHeap.insert(17);
maxHeap.insert(10);
maxHeap.insert(84);
maxHeap.insert(19);
maxHeap.insert(6);
maxHeap.insert(22);
maxHeap.insert(9);
maxHeap.print();
System.out.println("The max val is "
+ maxHeap.extractMax());
}
}
Java
// Java program to demonstrate working
// of PriorityQueue as a Max Heap
import java.util.*;
class Example {
public static void main(String args[])
{
// Creating empty priority queue
PriorityQueue pQueue
= new PriorityQueue(
Collections.reverseOrder());
// Adding items to the pQueue using add()
pQueue.add(10);
pQueue.add(30);
pQueue.add(20);
pQueue.add(400);
// Printing the most priority element
System.out.println("Head value using peek function:"
+ pQueue.peek());
// Printing all elements
System.out.println("The queue elements:");
Iterator itr = pQueue.iterator();
while (itr.hasNext())
System.out.println(itr.next());
// Removing the top priority element (or head) and
// printing the modified pQueue using poll()
pQueue.poll();
System.out.println("After removing an element "
+ "with poll function:");
Iterator itr2 = pQueue.iterator();
while (itr2.hasNext())
System.out.println(itr2.next());
// Removing 30 using remove()
pQueue.remove(30);
System.out.println("after removing 30 with"
+ " remove function:");
Iterator itr3 = pQueue.iterator();
while (itr3.hasNext())
System.out.println(itr3.next());
// Check if an element is present using contains()
boolean b = pQueue.contains(20);
System.out.println("Priority queue contains 20 "
+ "or not?: " + b);
// Getting objects from the queue using toArray()
// in an array and print the array
Object[] arr = pQueue.toArray();
System.out.println("Value in array: ");
for (int i = 0; i < arr.length; i++)
System.out.println("Value: "
+ arr[i].toString());
}
}
输出
The Max Heap is
PARENT : 84 LEFT CHILD : 22 RIGHT CHILD :19
PARENT : 22 LEFT CHILD : 17 RIGHT CHILD :10
PARENT : 19 LEFT CHILD : 5 RIGHT CHILD :6
PARENT : 17 LEFT CHILD : 3 RIGHT CHILD :9
The max val is 84
使用库函数
我们使用 PriorityQueue 类在Java实现堆。默认情况下,Min Heap 由此类实现。为了实现最大堆,我们使用 Collections.reverseOrder()
Java
// Java program to demonstrate working
// of PriorityQueue as a Max Heap
import java.util.*;
class Example {
public static void main(String args[])
{
// Creating empty priority queue
PriorityQueue pQueue
= new PriorityQueue(
Collections.reverseOrder());
// Adding items to the pQueue using add()
pQueue.add(10);
pQueue.add(30);
pQueue.add(20);
pQueue.add(400);
// Printing the most priority element
System.out.println("Head value using peek function:"
+ pQueue.peek());
// Printing all elements
System.out.println("The queue elements:");
Iterator itr = pQueue.iterator();
while (itr.hasNext())
System.out.println(itr.next());
// Removing the top priority element (or head) and
// printing the modified pQueue using poll()
pQueue.poll();
System.out.println("After removing an element "
+ "with poll function:");
Iterator itr2 = pQueue.iterator();
while (itr2.hasNext())
System.out.println(itr2.next());
// Removing 30 using remove()
pQueue.remove(30);
System.out.println("after removing 30 with"
+ " remove function:");
Iterator itr3 = pQueue.iterator();
while (itr3.hasNext())
System.out.println(itr3.next());
// Check if an element is present using contains()
boolean b = pQueue.contains(20);
System.out.println("Priority queue contains 20 "
+ "or not?: " + b);
// Getting objects from the queue using toArray()
// in an array and print the array
Object[] arr = pQueue.toArray();
System.out.println("Value in array: ");
for (int i = 0; i < arr.length; i++)
System.out.println("Value: "
+ arr[i].toString());
}
}
输出
Head value using peek function:400
The queue elements:
400
30
20
10
After removing an element with poll function:
30
10
20
after removing 30 with remove function:
20
10
Priority queue contains 20 or not?: true
Value in array:
Value: 20
Value: 10