📜  为键1到N构造所有可能的BST

📅  最后修改于: 2021-05-24 23:46:29             🧑  作者: Mango

本文中,首先讨论了可能的BST(二进制搜索树)的数量,然后讨论了所有可能的BST的构造。

1..N中的密钥有多少个结构唯一的BST?

For example, for N = 2, there are 2 unique BSTs
     1               2  
      \            /
       2         1 

For N = 3, there are 5 possible BSTs
  1              3        3         2      1
    \           /        /        /  \      \
     3        2         1        1    3      2
    /       /            \                    \
   2      1               2                    3

强烈建议您最小化浏览器,然后自己尝试。

我们知道,左子树中的所有节点均小于根,而右子树中的所有节点均大于根,因此,如果我们将第ith个数作为根,则从1到i-1的所有数字都将在左子树中,而i + 1到N将是在正确的子树中。如果1到i-1可以形成x棵不同的树,而i + 1到N可以从y个不同的树中形成,那么当第i个数为根时,我们将有x * y个树,并且根也有N个选择,因此我们可以简单地进行迭代从1到N表示根,另一个循环表示左右子树。如果仔细观察,我们会发现该计数基本上是第n个加泰罗尼亚语数字。我们在这里讨论了找到第n个加泰罗尼亚数的不同方法。

如何构造密钥1..N的所有BST?
这个想法是维护所有BST根目录。递归构造所有可能的左和右子树。为每对左右子树创建一个树,并将该树添加到列表中。下面是详细的算法。

1) Initialize list of BSTs as empty.  
2) For every number i where i varies from 1 to N, do following
......a)  Create a new node with key as 'i', let this node be 'node'
......b)  Recursively construct list of all left subtrees.
......c)  Recursively construct list of all right subtrees.
3) Iterate for all left subtrees
   a) For current leftsubtree, iterate for all right subtrees
        Add current left and right subtrees to 'node' and add
        'node' to list.

以下是上述想法的实现。

C++
// A C++ prgroam to contrcut all unique BSTs for keys from 1 to n
#include 
using namespace std;
  
//  node structure
struct node
{
    int key;
    struct node *left, *right;
};
  
// A utility function to create a new BST node
struct node *newNode(int item)
{
    struct node *temp =  new node;
    temp->key = item;
    temp->left = temp->right = NULL;
    return temp;
}
  
// A utility function to do preorder traversal of BST
void preorder(struct node *root)
{
    if (root != NULL)
    {
        cout << root->key << " ";
        preorder(root->left);
        preorder(root->right);
    }
}
  
//  function for constructing trees
vector constructTrees(int start, int end)
{
    vector list;
  
    /*  if start > end   then subtree will be empty so returning NULL
        in the list */
    if (start > end)
    {
        list.push_back(NULL);
        return list;
    }
  
    /*  iterating through all values from start to end  for constructing\
        left and right subtree recursively  */
    for (int i = start; i <= end; i++)
    {
        /*  constructing left subtree   */
        vector leftSubtree  = constructTrees(start, i - 1);
  
        /*  constructing right subtree  */
        vector rightSubtree = constructTrees(i + 1, end);
  
        /*  now looping through all left and right subtrees and connecting
            them to ith root  below  */
        for (int j = 0; j < leftSubtree.size(); j++)
        {
            struct node* left = leftSubtree[j];
            for (int k = 0; k < rightSubtree.size(); k++)
            {
                struct node * right = rightSubtree[k];
                struct node * node = newNode(i);// making value i as root
                node->left = left;              // connect left subtree
                node->right = right;            // connect right subtree
                list.push_back(node);           // add this tree to list
            }
        }
    }
    return list;
}
  
// Driver Program to test above functions
int main()
{
    // Construct all possible BSTs
    vector totalTreesFrom1toN = constructTrees(1, 3);
  
  
    /*  Printing preorder traversal of all constructed BSTs   */
    cout << "Preorder traversals of all constructed BSTs are \n";
    for (int i = 0; i < totalTreesFrom1toN.size(); i++)
    {
        preorder(totalTreesFrom1toN[i]);
        cout << endl;
    }
    return 0;
}


Java
// A Java prgroam to contrcut all unique BSTs for keys from 1 to n
import java.util.ArrayList;
public class Main {
  
    //  function for constructing trees 
    static ArrayList constructTrees(int start, int end) 
    { 
        ArrayList list=new ArrayList<>();
        /*  if start > end   then subtree will be empty so returning NULL 
            in the list */
        if (start > end) 
        { 
            list.add(null); 
            return list; 
        } 
    
        /*  iterating through all values from start to end  for constructing\ 
            left and right subtree recursively  */
        for (int i = start; i <= end; i++) 
        { 
            /*  constructing left subtree   */
            ArrayList leftSubtree  = constructTrees(start, i - 1); 
    
            /*  constructing right subtree  */
            ArrayList rightSubtree = constructTrees(i + 1, end); 
    
            /*  now looping through all left and right subtrees and connecting 
                them to ith root  below  */
            for (int j = 0; j < leftSubtree.size(); j++) 
            { 
                Node left = leftSubtree.get(j); 
                for (int k = 0; k < rightSubtree.size(); k++) 
                { 
                    Node right = rightSubtree.get(k); 
                    Node node = new Node(i);        // making value i as root 
                    node.left = left;              // connect left subtree 
                    node.right = right;            // connect right subtree 
                    list.add(node);                // add this tree to list 
                } 
            } 
        } 
        return list; 
    } 
  
    // A utility function to do preorder traversal of BST 
    static void preorder(Node root) 
    { 
        if (root != null) 
        { 
            System.out.print(root.key+" ") ;
            preorder(root.left); 
            preorder(root.right); 
        } 
    } 
  
    public static void main(String args[]) 
    {
        ArrayList totalTreesFrom1toN = constructTrees(1, 3);
        /*  Printing preorder traversal of all constructed BSTs   */
        System.out.println("Preorder traversals of all constructed BSTs are ");
        for (int i = 0; i < totalTreesFrom1toN.size(); i++) 
        { 
            preorder(totalTreesFrom1toN.get(i)); 
            System.out.println();
        } 
    }
}
  
//  node structure 
class Node 
{ 
    int key; 
    Node left, right; 
    Node(int data)
    {
        this.key=data;
        left=right=null;
    }
}; 
//This code is contributed by Gaurav Tiwari


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, item): 
        self.key=item
        self.left = None
        self.right = None
  
# A utility function to do preorder 
# traversal of BST 
def preorder(root) :
  
    if (root != None) :
      
        print(root.key, end = " " )
        preorder(root.left) 
        preorder(root.right) 
      
# function for constructing trees 
def constructTrees(start, end): 
  
    list = [] 
  
    """ if start > end then subtree will be 
        empty so returning None in the list """
    if (start > end) :
      
        list.append(None) 
        return list
      
    """ iterating through all values from 
        start to end for constructing
        left and right subtree recursively """
    for i in range(start, end + 1): 
      
        """ constructing left subtree """
        leftSubtree = constructTrees(start, i - 1) 
  
        """ constructing right subtree """
        rightSubtree = constructTrees(i + 1, end) 
  
        """ now looping through all left and 
            right subtrees and connecting 
            them to ith root below """
        for j in range(len(leftSubtree)) :
            left = leftSubtree[j] 
            for k in range(len(rightSubtree)): 
                right = rightSubtree[k] 
                node = newNode(i)   # making value i as root 
                node.left = left    # connect left subtree 
                node.right = right    # connect right subtree 
                list.append(node)    # add this tree to list 
    return list
  
# Driver Code 
if __name__ == '__main__':
  
    # Construct all possible BSTs 
    totalTreesFrom1toN = constructTrees(1, 3) 
  
    """ Printing preorder traversal of 
        all constructed BSTs """
    print("Preorder traversals of all", 
                "constructed BSTs are") 
    for i in range(len(totalTreesFrom1toN)): 
        preorder(totalTreesFrom1toN[i])
        print()
  
# This code is contributed by
# Shubham Singh(SHUBHAMSINGH10)


C#
// C# prgroam to contrcut all 
// unique BSTs for keys from 1 to n 
using System.Collections;
using System;
  
class GFG 
{ 
  
    // function for constructing trees 
    static ArrayList constructTrees(int start, int end) 
    { 
        ArrayList list = new ArrayList();
          
        /* if start > end then subtree will 
        be empty so returning NULL 
        in the list */
        if (start > end) 
        { 
            list.Add(null); 
            return list; 
        } 
      
        /* iterating through all values from 
        start to end for constructing\ 
        left and right subtree recursively */
        for (int i = start; i <= end; i++) 
        { 
            /* constructing left subtree */
            ArrayList leftSubtree = constructTrees(start, i - 1); 
      
            /* constructing right subtree */
            ArrayList rightSubtree = constructTrees(i + 1, end); 
      
            /* now looping through all left and
            right subtrees and connecting 
            them to ith root below */
            for (int j = 0; j < leftSubtree.Count; j++) 
            { 
                Node left = (Node)leftSubtree[j]; 
                for (int k = 0; k < rightSubtree.Count; k++) 
                { 
                    Node right = (Node)rightSubtree[k]; 
                      
                    // making value i as root 
                    Node node = new Node(i);
                      
                    // connect left subtree 
                    node.left = left;
                      
                    // connect right subtree 
                    node.right = right;     
                      
                    // Add this tree to list 
                    list.Add(node);         
                } 
            } 
        } 
        return list; 
    } 
  
    // A utility function to do 
    // preorder traversal of BST 
    static void preorder(Node root) 
    { 
        if (root != null) 
        { 
            Console.Write(root.key+" ") ; 
            preorder(root.left); 
            preorder(root.right); 
        } 
    } 
  
    // Driver code
    public static void Main(String []args) 
    { 
        ArrayList totalTreesFrom1toN = constructTrees(1, 3); 
          
        /* Printing preorder traversal 
        of all constructed BSTs */
        Console.WriteLine("Preorder traversals of all" +
                                "constructed BSTs are "); 
        for (int i = 0; i < totalTreesFrom1toN.Count; i++) 
        { 
            preorder((Node)totalTreesFrom1toN[i]); 
            Console.WriteLine(); 
        } 
    } 
      
// node structure 
public class Node 
{ 
    public int key; 
    public Node left, right; 
    public Node(int data) 
    { 
        this.key=data; 
        left=right=null; 
    } 
}; 
} 
  
// This code is contributed by Arnab Kundu


输出:

Preorder traversals of all constructed BSTs are
1 2 3
1 3 2
2 1 3
3 1 2
3 2 1