📜  不使用数组将BST转换为最小堆

📅  最后修改于: 2021-05-24 22:08:20             🧑  作者: Mango

给定二叉搜索树,将其转换为包含O(n)时间相同元素的Min-Heap。就地执行此操作。

Input: Binary Search Tree
        8
     /    \
    4      12
  /  \     /  \
 2    6   10  14


Output - Min Heap
       2
     /    \
   4        6
 /  \     /   \
8    10  12   14
[Or any other tree that follows Min Heap
 properties and has same keys]

如果允许我们使用额外的空间,则可以对树进行有序遍历,并将键存储在辅助数组中。当我们在BST上进行有序遍历时,将对数组进行排序。最后,我们从排序后的数组构造一个完整的二叉树。我们通过从排序数组中获取下一个最小元素,从左到右逐级构造二叉树。构造的二叉树将是min-Heap。该解决方案可以在O(n)的时间内工作,但不能就地解决。
如何就地进行?
这个想法是首先将二进制搜索树转换为排序的链表。我们可以通过按顺序遍历BST来做到这一点。我们在当前链接列表的开头添加节点,并使用指向head指针的指针更新列表的开头。由于我们在开始处插入,为了保持排序顺序,我们首先在左子树之前遍历右子树。即进行反向有序遍历。
最后,通过适当地设置左右指针,将排序后的链表转换为min-Heap。我们可以通过使用队列对部分构建的Min-Heap Tree进行Level顺序遍历并同时遍历链接列表来实现此目的。在每一步中,我们从队列中获取父节点,将链接列表的后两个节点作为父节点的子节点,然后将后两个节点排入队列。在对链表进行排序时,将保留min-heap属性。
以下是上述想法的实现–

C++
// Program to convert a BST into a Min-Heap
// in O(n) time and in-place
#include 
using namespace std;
 
// Node for BST/Min-Heap
struct Node
{
    int data;
    Node *left, *right;
};
 
// Utility function for allocating node for BST
Node* newNode(int data)
{
    Node* node = new Node;
    node->data = data;
    node->left = node->right = NULL;
    return node;
}
 
// Utility function to print Min-heap level by level
void printLevelOrder(Node *root)
{
    // Base Case
    if (root == NULL)  return;
 
    // Create an empty queue for level order traversal
    queue q;
    q.push(root);
 
    while (!q.empty())
    {
        int nodeCount = q.size();
        while (nodeCount > 0)
        {
            Node *node = q.front();
            cout << node->data << " ";
            q.pop();
            if (node->left)
                q.push(node->left);
            if (node->right)
                q.push(node->right);
            nodeCount--;
        }
        cout << endl;
    }
}
 
// A simple recursive function to convert a given
// Binary Search tree to Sorted Linked List
// root     --> Root of Binary Search Tree
// head_ref --> Pointer to head node of created
//              linked list
void BSTToSortedLL(Node* root, Node** head_ref)
{
    // Base cases
    if(root == NULL)
        return;
 
    // Recursively convert right subtree
    BSTToSortedLL(root->right, head_ref);
 
    // insert root into linked list
    root->right = *head_ref;
 
    // Change left pointer of previous head
    // to point to NULL
    if (*head_ref != NULL)
        (*head_ref)->left = NULL;
 
    // Change head of linked list
    *head_ref = root;
 
    // Recursively convert left subtree
    BSTToSortedLL(root->left, head_ref);
}
 
// Function to convert a sorted Linked
// List to Min-Heap.
// root --> Root of Min-Heap
// head --> Pointer to head node of sorted
//              linked list
void SortedLLToMinHeap(Node* &root, Node* head)
{
    // Base Case
    if (head == NULL)
        return;
 
    // queue to store the parent nodes
    queue q;
 
    // The first node is always the root node
    root = head;
 
    // advance the pointer to the next node
    head = head->right;
 
    // set right child to NULL
    root->right = NULL;
 
    // add first node to the queue
    q.push(root);
 
    // run until the end of linked list is reached
    while (head)
    {
        // Take the parent node from the q and remove it from q
        Node* parent = q.front();
        q.pop();
 
        // Take next two nodes from the linked list and
        // Add them as children of the current parent node
        // Also in push them into the queue so that
        // they will be parents to the future nodes
        Node *leftChild = head;
        head = head->right;        // advance linked list to next node
        leftChild->right = NULL; // set its right child to NULL
        q.push(leftChild);
 
        // Assign the left child of parent
        parent->left = leftChild;
 
        if (head)
        {
            Node *rightChild = head;
            head = head->right; // advance linked list to next node
            rightChild->right = NULL; // set its right child to NULL
            q.push(rightChild);
 
            // Assign the right child of parent
            parent->right = rightChild;
        }
    }
}
 
// Function to convert BST into a Min-Heap
// without using any extra space
Node* BSTToMinHeap(Node* &root)
{
    // head of Linked List
    Node *head = NULL;
 
    // Convert a given BST to Sorted Linked List
    BSTToSortedLL(root, &head);
 
    // set root as NULL
    root = NULL;
 
    // Convert Sorted Linked List to Min-Heap
    SortedLLToMinHeap(root, head);
}
 
// Driver code
int main()
{
    /* Constructing below tree
                8
              /   \
             4     12
           /  \   /  \
          2    6 10   14
     */
 
    Node* root = newNode(8);
    root->left = newNode(4);
    root->right = newNode(12);
    root->right->left = newNode(10);
    root->right->right = newNode(14);
    root->left->left = newNode(2);
    root->left->right = newNode(6);
 
    BSTToMinHeap(root);
 
    /* Output - Min Heap
                2
              /   \
             4     6
           /  \   /  \
          8   10 12   14
     */
 
    printLevelOrder(root);
 
    return 0;
}


Java
// Java Program to convert a BST into a Min-Heap
// in O(n) time and in-place
import java.util.*;
 
class GFG
{
     
// Node for BST/Min-Heap
static class Node
{
    int data;
    Node left, right;
};
 
// Utility function for allocating node for BST
static Node newNode(int data)
{
    Node node = new Node();
    node.data = data;
    node.left = node.right = null;
    return node;
}
 
// Utility function to print Min-heap level by level
static void printLevelOrder(Node root)
{
    // Base Case
    if (root == null) return;
 
    // Create an empty queue for level order traversal
    Queue q = new LinkedList<>();
    q.add(root);
 
    while (q.size() > 0)
    {
        int nodeCount = q.size();
        while (nodeCount > 0)
        {
            Node node = q.peek();
            System.out.print( node.data + " ");
            q.remove();
            if (node.left != null)
                q.add(node.left);
            if (node.right != null)
                q.add(node.right);
            nodeCount--;
        }
        System.out.println();
    }
}
 
// A simple recursive function to convert a given
// Binary Search tree to Sorted Linked List
// root     -. Root of Binary Search Tree
// head_ref -. Pointer to head node of created
//             linked list
static Node BSTToSortedLL(Node root, Node head_ref)
{
    // Base cases
    if(root == null)
        return head_ref;
 
    // Recursively convert right subtree
    head_ref = BSTToSortedLL(root.right, head_ref);
 
    // insert root into linked list
    root.right = head_ref;
 
    // Change left pointer of previous head
    // to point to null
    if (head_ref != null)
        (head_ref).left = null;
 
    // Change head of linked list
    head_ref = root;
 
    // Recursively convert left subtree
    head_ref = BSTToSortedLL(root.left, head_ref);
    return head_ref;
}
 
// Function to convert a sorted Linked
// List to Min-Heap.
// root -. Root of Min-Heap
// head -. Pointer to head node of sorted
//             linked list
static Node SortedLLToMinHeap(Node root, Node head)
{
    // Base Case
    if (head == null)
        return null;
 
    // queue to store the parent nodes
    Queue q = new LinkedList<>();
 
    // The first node is always the root node
    root = head;
 
    // advance the pointer to the next node
    head = head.right;
 
    // set right child to null
    root.right = null;
 
    // add first node to the queue
    q.add(root);
 
    // run until the end of linked list is reached
    while (head != null)
    {
        // Take the parent node from the q and remove it from q
        Node parent = q.peek();
        q.remove();
 
        // Take next two nodes from the linked list and
        // Add them as children of the current parent node
        // Also in add them into the queue so that
        // they will be parents to the future nodes
        Node leftChild = head;
        head = head.right;     // advance linked list to next node
        leftChild.right = null; // set its right child to null
        q.add(leftChild);
 
        // Assign the left child of parent
        parent.left = leftChild;
 
        if (head != null)
        {
            Node rightChild = head;
            head = head.right; // advance linked list to next node
            rightChild.right = null; // set its right child to null
            q.add(rightChild);
 
            // Assign the right child of parent
            parent.right = rightChild;
        }
    }
    return root;
}
 
// Function to convert BST into a Min-Heap
// without using any extra space
static Node BSTToMinHeap(Node root)
{
    // head of Linked List
    Node head = null;
 
    // Convert a given BST to Sorted Linked List
    head = BSTToSortedLL(root, head);
     
    // set root as null
    root = null;
 
    // Convert Sorted Linked List to Min-Heap
    root = SortedLLToMinHeap(root, head);
    return root;
}
 
// Driver code
public static void main(String args[])
{
    /* Constructing below tree
                8
            / \
            4     12
        / \ / \
        2 6 10 14
    */
 
    Node root = newNode(8);
    root.left = newNode(4);
    root.right = newNode(12);
    root.right.left = newNode(10);
    root.right.right = newNode(14);
    root.left.left = newNode(2);
    root.left.right = newNode(6);
 
    root = BSTToMinHeap(root);
 
    /* Output - Min Heap
                2
            / \
            4     6
        / \ / \
        8 10 12 14
    */
 
    printLevelOrder(root);
}
}
 
// This code is contributed by andrew1234


Python3
# Python3 prgroam to contrcut all unique
# BSTs for keys from 1 to n
 
# Binary Tree Node
""" A utility function to create a
new BST node """
class newNode:
 
    # Construct to create a newNode
    def __init__(self, data):
        self.data = data
        self.left = None
        self.right = None
 
# Utility function to print Min-heap
# level by level
def printLevelOrder(root):
     
    # Base Case
    if (root == None):
        return
 
    # Create an empty queue for level
    # order traversal
    q = []
    q.append(root)
 
    while (len(q)):
        nodeCount = len(q)
        while (nodeCount > 0) :
         
            node = q[0]
            print(node.data, end = " " )
            q.pop(0)
            if (node.left) :
                q.append(node.left)
            if (node.right) :
                q.append(node.right)
            nodeCount -= 1
        print()
 
# A simple recursive function to convert a
# given Binary Search tree to Sorted Linked
# List root     -. Root of Binary Search Tree
def BSTToSortedLL(root, head_ref):
 
    # Base cases
    if(root == None) :
        return
 
    # Recursively convert right subtree
    BSTToSortedLL(root.right, head_ref)
 
    # insert root into linked list
    root.right = head_ref[0]
 
    # Change left pointer of previous
    # head to point to None
    if (head_ref[0] != None):
        (head_ref[0]).left = None
 
    # Change head of linked list
    head_ref[0] = root
 
    # Recursively convert left subtree
    BSTToSortedLL(root.left, head_ref)
 
# Function to convert a sorted Linked
# List to Min-Heap.
# root -. root[0] of Min-Heap
# head -. Pointer to head node of
#          sorted linked list
def SortedLLToMinHeap( root, head) :
 
    # Base Case
    if (head == None) :
        return
 
    # queue to store the parent nodes
    q = []
 
    # The first node is always the
    # root node
    root[0] = head[0]
 
    # advance the pointer to the next node
    head[0] = head[0].right
 
    # set right child to None
    root[0].right = None
 
    # add first node to the queue
    q.append(root[0])
 
    # run until the end of linked list
    # is reached
    while (head[0] != None) :
     
        # Take the parent node from the q
        # and remove it from q
        parent = q[0]
        q.pop(0)
 
        # Take next two nodes from the linked
        # list and Add them as children of the
        # current parent node. Also in push them
        # into the queue so that they will be
        # parents to the future nodes
        leftChild = head[0]
        head[0] = head[0].right     # advance linked list to next node
        leftChild.right = None # set its right child to None
        q.append(leftChild)
 
        # Assign the left child of parent
        parent.left = leftChild
 
        if (head) :
            rightChild = head[0]
            head[0] = head[0].right # advance linked list to next node
            rightChild.right = None # set its right child to None
            q.append(rightChild)
 
            # Assign the right child of parent
            parent.right = rightChild
 
# Function to convert BST into a Min-Heap
# without using any extra space
def BSTToMinHeap(root):
 
    # head of Linked List
    head = [None]
 
    # Convert a given BST to Sorted Linked List
    BSTToSortedLL(root, head)
     
    # set root as None
    root = [None]
 
    # Convert Sorted Linked List to Min-Heap
    SortedLLToMinHeap(root, head)
    return root
 
# Driver Code
if __name__ == '__main__':
 
    """ Constructing below tree
                8
            / \
            4     12
        / \ / \
        2 6 10 14
    """
    root = newNode(8)
    root.left = newNode(4)
    root.right = newNode(12)
    root.right.left = newNode(10)
    root.right.right = newNode(14)
    root.left.left = newNode(2)
    root.left.right = newNode(6)
 
    root = BSTToMinHeap(root)
     
    """ Output - Min Heap
                2
            / \
            4     6
        / \ / \
        8 10 12 14
    """
    printLevelOrder(*root)
 
# This code is contributed by
# Shubham Singh(SHUBHAMSINGH10)


C#
// C# Program to convert a BST into a Min-Heap
// in O(n) time and in-place
using System;
using System.Collections.Generic;
public class GFG
{
 
  // Node for BST/Min-Heap
  public
    class Node
    {
      public
        int data;
      public
        Node left, right;
    };
 
  // Utility function for allocating node for BST
  static Node newNode(int data)
  {
    Node node = new Node();
    node.data = data;
    node.left = node.right = null;
    return node;
  }
 
  // Utility function to print Min-heap level by level
  static void printLevelOrder(Node root)
  {
 
    // Base Case
    if (root == null) return;
 
    // Create an empty queue for level order traversal
    Queue q = new Queue();
    q.Enqueue(root);
 
    while (q.Count > 0)
    {
      int nodeCount = q.Count;
      while (nodeCount > 0)
      {
        Node node = q.Peek();
        Console.Write( node.data + " ");
        q.Dequeue();
        if (node.left != null)
          q.Enqueue(node.left);
        if (node.right != null)
          q.Enqueue(node.right);
        nodeCount--;
      }
      Console.WriteLine();
    }
  }
 
  // A simple recursive function to convert a given
  // Binary Search tree to Sorted Linked List
  // root     -. Root of Binary Search Tree
  // head_ref -. Pointer to head node of created
  //             linked list
  static Node BSTToSortedLL(Node root, Node head_ref)
  {
 
    // Base cases
    if(root == null)
      return head_ref;
 
    // Recursively convert right subtree
    head_ref = BSTToSortedLL(root.right, head_ref);
 
    // insert root into linked list
    root.right = head_ref;
 
    // Change left pointer of previous head
    // to point to null
    if (head_ref != null)
      (head_ref).left = null;
 
    // Change head of linked list
    head_ref = root;
 
    // Recursively convert left subtree
    head_ref = BSTToSortedLL(root.left, head_ref);
    return head_ref;
  }
 
  // Function to convert a sorted Linked
  // List to Min-Heap.
  // root -. Root of Min-Heap
  // head -. Pointer to head node of sorted
  //             linked list
  static Node SortedLLToMinHeap(Node root, Node head)
  {
    // Base Case
    if (head == null)
      return null;
 
    // queue to store the parent nodes
    Queue q = new Queue();
 
    // The first node is always the root node
    root = head;
 
    // advance the pointer to the next node
    head = head.right;
 
    // set right child to null
    root.right = null;
 
    // add first node to the queue
    q.Enqueue(root);
 
    // run until the end of linked list is reached
    while (head != null)
    {
 
      // Take the parent node from the q and remove it from q
      Node parent = q.Peek();
      q.Dequeue();
 
      // Take next two nodes from the linked list and
      // Add them as children of the current parent node
      // Also in add them into the queue so that
      // they will be parents to the future nodes
      Node leftChild = head;
      head = head.right;     // advance linked list to next node
      leftChild.right = null; // set its right child to null
      q.Enqueue(leftChild);
 
      // Assign the left child of parent
      parent.left = leftChild;
      if (head != null)
      {
        Node rightChild = head;
        head = head.right; // advance linked list to next node
        rightChild.right = null; // set its right child to null
        q.Enqueue(rightChild);
 
        // Assign the right child of parent
        parent.right = rightChild;
      }
    }
    return root;
  }
 
  // Function to convert BST into a Min-Heap
  // without using any extra space
  static Node BSTToMinHeap(Node root)
  {
 
    // head of Linked List
    Node head = null;
 
    // Convert a given BST to Sorted Linked List
    head = BSTToSortedLL(root, head);
 
    // set root as null
    root = null;
 
    // Convert Sorted Linked List to Min-Heap
    root = SortedLLToMinHeap(root, head);
    return root;
  }
 
  // Driver code
  public static void Main(String []args)
  {
 
    /* Constructing below tree
                8
            / \
            4     12
        / \ / \
        2 6 10 14
    */
 
    Node root = newNode(8);
    root.left = newNode(4);
    root.right = newNode(12);
    root.right.left = newNode(10);
    root.right.right = newNode(14);
    root.left.left = newNode(2);
    root.left.right = newNode(6);
 
    root = BSTToMinHeap(root);
 
    /* Output - Min Heap
                2
            / \
            4     6
        / \ / \
        8 10 12 14
    */
    printLevelOrder(root);
  }
}
 
// This code is contributed by aashish1995


输出 :

2 
4 6 
8 10 12 14