📜  Java的最大堆

📅  最后修改于: 2021-10-28 01:52:01             🧑  作者: Mango

最大堆是一个完整的二叉树,其中每个内部节点中的值大于或等于该节点的子节点中的值。

将堆的元素映射到数组是微不足道的:如果节点存储索引 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