Java中的最小堆
Min-Heap 是一棵完全二叉树,其中每个内部节点中的值都小于或等于该节点子节点中的值。将堆的元素映射到数组是很简单的:如果一个节点存储了一个索引k ,那么它的左孩子存储在索引2k + 1 ,它的右孩子存储在索引2k + 2 。
插图:
5 13
/ \ / \
10 15 16 31
/ / \ / \
30 41 51 100 41
让我们看一下 Min heap 的表示。所以基本上Min Heap是一棵完全二叉树。最小堆通常表示为一个数组。根元素将位于Arr[0] 。对于任何第 i 个节点,即Arr[i]
- Arr[(i -1) / 2]返回其父节点。
- Arr[(2 * i) + 1]返回其左子节点。
- Arr[(2 * i) + 2]返回其右子节点。
现在让我们讨论 Min Heap 上的操作,如下所示:
- getMin():返回最小堆的根元素。此操作的时间复杂度为O(1) 。
- extractMin():从 MinHeap 中移除最小元素。此操作的时间复杂度为O(Log n) ,因为此操作需要在删除根后维护堆属性(通过调用 heapify())。
- insert():插入新密钥需要O(Log n)时间。我们在树的末尾添加一个新键。如果一个新的 key 比它的 parent 大,那么我们不需要做任何事情。否则,我们需要向上遍历来修复被破坏的堆属性。
示例 1:
Java
// Java Program to Implement Heaps
// by Illustrating Min Heap
// Main class (MinHeap)
class GFG {
// Member variables of this class
private int[] Heap;
private int size;
private int maxsize;
// Initializing front as static with unity
private static final int FRONT = 1;
// Constructor of this class
public MinHeap(int maxsize)
{
// This keyword refers to current object itself
this.maxsize = maxsize;
this.size = 0;
Heap = new int[this.maxsize + 1];
Heap[0] = Integer.MIN_VALUE;
}
// Method 1
// Returning the position of
// the parent for the node currently
// at pos
private int parent(int pos) { return pos / 2; }
// Method 2
// Returning the position of the
// left child for the node currently at pos
private int leftChild(int pos) { return (2 * pos); }
// Method 3
// Returning the position of
// the right child for the node currently
// at pos
private int rightChild(int pos)
{
return (2 * pos) + 1;
}
// Method 4
// Returning true if the passed
// node is a leaf node
private boolean isLeaf(int pos)
{
if (pos > (size / 2) && pos <= size) {
return true;
}
return false;
}
// Method 5
// To swap two nodes of the heap
private void swap(int fpos, int spos)
{
int tmp;
tmp = Heap[fpos];
Heap[fpos] = Heap[spos];
Heap[spos] = tmp;
}
// Method 6
// To heapify the node at pos
private void minHeapify(int pos)
{
// If the node is a non-leaf node and greater
// than any of its child
if (!isLeaf(pos)) {
if (Heap[pos] > Heap[leftChild(pos)]
|| Heap[pos] > Heap[rightChild(pos)]) {
// Swap with the left child and heapify
// the left child
if (Heap[leftChild(pos)]
< Heap[rightChild(pos)]) {
swap(pos, leftChild(pos));
minHeapify(leftChild(pos));
}
// Swap with the right child and heapify
// the right child
else {
swap(pos, rightChild(pos));
minHeapify(rightChild(pos));
}
}
}
}
// Method 7
// To insert a node into the heap
public void insert(int element)
{
if (size >= maxsize) {
return;
}
Heap[++size] = element;
int current = size;
while (Heap[current] < Heap[parent(current)]) {
swap(current, parent(current));
current = parent(current);
}
}
// Method 8
// To print the contents of the heap
public void print()
{
for (int i = 1; i <= size / 2; i++) {
// Printing the parent and both childrens
System.out.print(
" PARENT : " + Heap[i]
+ " LEFT CHILD : " + Heap[2 * i]
+ " RIGHT CHILD :" + Heap[2 * i + 1]);
// By here new line is required
System.out.println();
}
}
// Method 9
// To remove and return the minimum
// element from the heap
public int remove()
{
int popped = Heap[FRONT];
Heap[FRONT] = Heap[size--];
minHeapify(FRONT);
return popped;
}
// Method 10
// Main driver method
public static void main(String[] arg)
{
// Display message
System.out.println("The Min Heap is ");
// Creating object opf class in main() methodn
GFG minHeap = new GFG(15);
// Inserting element to minHeap
// using insert() method
// Custom input entries
minHeap.insert(5);
minHeap.insert(3);
minHeap.insert(17);
minHeap.insert(10);
minHeap.insert(84);
minHeap.insert(19);
minHeap.insert(6);
minHeap.insert(22);
minHeap.insert(9);
// Print all elements of the heap
minHeap.print();
// Removing minimum value from above heap
// and printing it
System.out.println("The Min val is "
+ minHeap.remove());
}
}
Java
// Java program to Demonstrate working of PriorityQueue
// Using Library Functions
// Importing utility classes
import java.util.*;
// Main class
class GFG {
// Main driver method
public static void main(String args[])
{
// Creating empty priority queue
PriorityQueue pQueue
= new PriorityQueue();
// Adding items to the priority queue
// using add() method
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:");
// Iterating over objects using Iterator
// so do creating an Iterator class
Iterator itr = pQueue.iterator();
// Iterating toill there is single element left in
// object using next() method
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:");
// Again creating iterator object
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:");
// Again creating iterator object
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 Min Heap is
PARENT : 3 LEFT CHILD : 5 RIGHT CHILD :6
PARENT : 5 LEFT CHILD : 9 RIGHT CHILD :84
PARENT : 6 LEFT CHILD : 19 RIGHT CHILD :17
PARENT : 9 LEFT CHILD : 22 RIGHT CHILD :10
The Min val is 3
We use PriorityQueue class to implement Heaps in Java. By default Min Heap is implemented by this class which is as shown in below example as follows:
示例 2:
Java
// Java program to Demonstrate working of PriorityQueue
// Using Library Functions
// Importing utility classes
import java.util.*;
// Main class
class GFG {
// Main driver method
public static void main(String args[])
{
// Creating empty priority queue
PriorityQueue pQueue
= new PriorityQueue();
// Adding items to the priority queue
// using add() method
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:");
// Iterating over objects using Iterator
// so do creating an Iterator class
Iterator itr = pQueue.iterator();
// Iterating toill there is single element left in
// object using next() method
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:");
// Again creating iterator object
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:");
// Again creating iterator object
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:10
The queue elements:
10
30
20
400
After removing an element with poll function:
20
30
400
after removing 30 with remove function:
20
400
Priority queue contains 20 or not?: true
Value in array:
Value: 20
Value: 400