📌  相关文章
📜  从给定的二叉树构造祖先矩阵

📅  最后修改于: 2022-05-13 01:57:18.947000             🧑  作者: Mango

从给定的二叉树构造祖先矩阵

给定一棵二叉树,其中所有值都从0n-1 。构造一个祖先矩阵mat[n][n] 。祖先矩阵定义如下。

mat[i][j] = 1 if i is ancestor of j
mat[i][j] = 0, otherwise

例子:

Input: Root of below Binary Tree.
          0
        /   \
       1     2
Output: 0 1 1
        0 0 0 
        0 0 0 

Input: Root of below Binary Tree.
           5
        /    \
       1      2
      /  \    /
     0    4  3
Output: 0 0 0 0 0 0 
        1 0 0 0 1 0 
        0 0 0 1 0 0 
        0 0 0 0 0 0 
        0 0 0 0 0 0 
        1 1 1 1 1 0

我们强烈建议您最小化您的浏览器并首先自己尝试。

方法一
这个想法是遍历树。遍历时,跟踪数组中的祖先。当我们访问一个节点时,我们将它添加到祖先数组并考虑邻接矩阵中的相应行。我们将其行中的所有祖先标记为 1。处理完一个节点及其所有子节点后,我们从祖先数组中删除该节点。

下面是上述想法的实现。

C++
// C++ program to construct ancestor matrix for
// given tree.
#include
using namespace std;
#define MAX 100
 
/* A binary tree node */
struct Node
{
    int data;
    Node *left, *right;
};
 
// Creating a global boolean matrix for simplicity
bool mat[MAX][MAX];
 
// anc[] stores all ancestors of current node.  This
// function fills ancestors for all nodes.
// It also returns size of tree.  Size of tree is
// used to print ancestor matrix.
int ancestorMatrixRec(Node *root, vector &anc)
{
    /* base case */
    if (root == NULL) return 0;;
 
    // Update all ancestors of current node
    int data = root->data;
    for (int i=0; ileft, anc);
    int r = ancestorMatrixRec(root->right, anc);
 
    // Remove data from list the list of ancestors
    // as all descendants of it are processed now.
    anc.pop_back();
 
    return l+r+1;
}
 
// This function mainly calls ancestorMatrixRec()
void ancestorMatrix(Node *root)
{
    // Create an empty ancestor array
    vector anc;
 
    // Fill ancestor matrix and find size of
    // tree.
    int n = ancestorMatrixRec(root, anc);
 
    // Print the filled values
    for (int i=0; idata = data;
    node->left = node->right = NULL;
    return (node);
}
 
/* Driver program to test above functions*/
int main()
{
    /* Construct the following binary tree
                5
              /   \
            1      2
          /  \    /
         0    4  3    */
    Node *root        = newnode(5);
    root->left        = newnode(1);
    root->right       = newnode(2);
    root->left->left  = newnode(0);
    root->left->right = newnode(4);
    root->right->left = newnode(3);
 
    ancestorMatrix(root);
 
    return 0;
}


Java
// Java Program to construct ancestor matrix for a given tree
import java.util.*;
 
class GFG
{
    // ancestorMatrix function to populate the matrix of
    public static void ancestorMatrix(Node root ,
                                    int matrix[][],int size)
    {
         
        // base case:
        if (root==null)
        return ;
         
        // call recursively for a preorder {left}
        ancestorMatrix(root.left, matrix, size);
         
        // call recursively for preorder {right}
        ancestorMatrix(root.right, matrix, size);
         
        // here we will reach the root node automatically
        // try solving on pen and paper
         
        if (root.left != null)
        {
            // make the current node as parent of its children node
            matrix[root.data][root.left.data] = 1;
             
            // iterate through all the columns of children node
            // all nodes which are children to
            // children of root node will also
            // be children of root node
            for (int i = 0; i < size; i++)
            {
                // if children of root node is a parent
                // of someone (i.e 1) then make that node
                // as children of root also
                if (matrix[root.left.data][i] == 1)
                matrix[root.data][i] = 1;
            }
        }
         
        // same procedure followed for right node as well
        if (root.right != null)
        {
            matrix[root.data][root.right.data] = 1;
             
            for (int i = 0; i < size; i++)
            {
                if (matrix[root.right.data][i]==1)
                matrix[root.data][i] = 1;
            }
        }
             
         
    }
     
    // Driver program to test the program
    public static void main(String[] args)
    {
         
        // construct the binary tree as follows
        Node tree_root = new Node(5);
        tree_root.left = new Node (1);
        tree_root.right = new Node(2);
        tree_root.left.left = new Node(0);
        tree_root.left.right = new Node(4);
        tree_root.right.left = new Node(3);
         
        // size of matrix
        int size = 6;
        int matrix [][] = new int[size][size];
         
        ancestorMatrix(tree_root, matrix, size);
         
        for (int i = 0; i < size; i++)
        {
            for (int j = 0; j < size; j++)
            {
                System.out.print(matrix[i][j]+" ");
            }
            System.out.println();
        }
    }
     
    // node class for tree node
    static class Node
    {
        public int data ;
        public Node left ,right;
        public Node (int data)
        {
            this.data = data;
            this.left = this.right = null;
        }
    }
}
 
// This code is contributed by Sparsh Singhal


Python3
# Python3 program to construct ancestor
# matrix for given tree.
 
class newnode:
    def __init__(self, data):
        self.data = data
        self.left = self.right = None
         
# anc[] stores all ancestors of current node.
# This function fills ancestors for all nodes.
# It also returns size of tree. Size of tree 
# is used to print ancestor matrix.
def ancestorMatrixRec(root, anc):
    global mat, MAX
     
    # base case
    if root == None:
        return 0
 
    # Update all ancestors of current node
    data = root.data
    for i in range(len(anc)):
        mat[anc[i]][data] = 1
 
    # Push data to list of ancestors
    anc.append(data)
 
    # Traverse left and right subtrees
    l = ancestorMatrixRec(root.left, anc)
    r = ancestorMatrixRec(root.right, anc)
 
    # Remove data from list the list of ancestors
    # as all descendants of it are processed now.
    anc.pop(-1)
 
    return l + r + 1
 
# This function mainly calls ancestorMatrixRec()
def ancestorMatrix(root):
     
    # Create an empty ancestor array
    anc = []
 
    # Fill ancestor matrix and find
    # size of tree.
    n = ancestorMatrixRec(root, anc)
 
    # Print the filled values
    for i in range(n):
        for j in range(n):
            print(mat[i][j], end = " ")
        print()
 
# Driver Code
MAX = 100
mat = [[0] * MAX for i in range(MAX)]
 
# Construct the following binary tree
#         5
#         / \
#     1     2
#     / \ /
#     0 4 3
root = newnode(5)
root.left = newnode(1)
root.right = newnode(2)
root.left.left = newnode(0)
root.left.right = newnode(4)
root.right.left = newnode(3)
 
ancestorMatrix(root)
 
# This code is contributed by PranchalK


C#
// C# Program to construct ancestor matrix for a given tree
using System;
 
class GFG
{
    // ancestorMatrix function to populate the matrix of
    public static void ancestorMatrix(Node root,
                        int [,]matrix, int size)
    {
 
        // base case:
        if (root == null)
        {
            return;
        }
 
        // call recursively for a preorder {left}
        ancestorMatrix(root.left, matrix, size);
 
        // call recursively for preorder {right}
        ancestorMatrix(root.right, matrix, size);
 
        // here we will reach the root node automatically
        // try solving on pen and paper
        if (root.left != null)
        {
            // make the current node as parent of its children node
            matrix[root.data,root.left.data] = 1;
 
            // iterate through all the columns of children node
            // all nodes which are children to
            // children of root node will also
            // be children of root node
            for (int i = 0; i < size; i++)
            {
                // if children of root node is a parent
                // of someone (i.e 1) then make that node
                // as children of root also
                if (matrix[root.left.data,i] == 1)
                {
                    matrix[root.data,i] = 1;
                }
            }
        }
 
        // same procedure followed for right node as well
        if (root.right != null)
        {
            matrix[root.data,root.right.data] = 1;
 
            for (int i = 0; i < size; i++)
            {
                if (matrix[root.right.data,i] == 1)
                {
                    matrix[root.data,i] = 1;
                }
            }
        }
 
    }
 
    // Driver code
    public static void Main(String[] args)
    {
 
        // construct the binary tree as follows
        Node tree_root = new Node(5);
        tree_root.left = new Node(1);
        tree_root.right = new Node(2);
        tree_root.left.left = new Node(0);
        tree_root.left.right = new Node(4);
        tree_root.right.left = new Node(3);
 
        // size of matrix
        int size = 6;
        int [,]matrix = new int[size,size];
 
        ancestorMatrix(tree_root, matrix, size);
 
        for (int i = 0; i < size; i++)
        {
            for (int j = 0; j < size; j++)
            {
                Console.Write(matrix[i,j] + " ");
            }
            Console.WriteLine();
        }
    }
 
    // node class for tree node
    public class Node
    {
 
        public int data;
        public Node left, right;
 
        public Node(int data)
        {
            this.data = data;
            this.left = this.right = null;
        }
    }
}
 
// This code is contributed by 29AjayKumar


Javascript


C++
// C++ program to construct ancestor matrix for
// given tree.
#include
using namespace std;
#define size 6
 
int M[size][size]={0};
 
/* A binary tree node */
struct Node
{
    int data;
    Node *left, *right;
};
 
/* Helper function to create a new node */
Node* newnode(int data)
{
    Node* node = new Node;
    node->data = data;
    node->left = node->right = NULL;
    return (node);
}
 
void printMatrix(){
        for(int i=0;idata;
             
        //Since there is no ancestor for root node,
        // so we doesn't assign it's value as 1           
        if(index==-1)index=root->data;
        else  M[index][preData]=1;   
     
    MatrixUtil(root->left,preData);
    MatrixUtil(root->right,preData);
}
 
void Matrix(Node *root){
    // Call Func MatrixUtil
    MatrixUtil(root,-1);
     
     
    //Applying Transitive Closure for the given Matrix
    for(int i=0;ileft     = newnode(1);
    root->right     = newnode(2);
    root->left->left = newnode(0);
    root->left->right = newnode(4);
    root->right->left = newnode(3);
 
    Matrix(root);
     
 
    return 0;
}


Java
// Java program to conancestor matrix for
// given tree. 
import java.util.*;
class GFG
{
  static final int size = 6;
 
  static int [][]M = new int[size][size];
 
  /* A binary tree node */
  static class Node
  {
    int data;
    Node left, right;
  };
 
  /* Helper function to create a new node */
  static Node newnode(int data)
  {
    Node node = new Node();
    node.data = data;
    node.left = node.right = null;
    return (node);
  }
 
  static void printMatrix()
  {
    for(int i = 0; i < size; i++)
    {
      for(int j = 0; j < size; j++)
        System.out.print(M[i][j] + " ");
      System.out.println();
    }       
  }
 
  // First PreOrder Traversal
  static void MatrixUtil(Node root, int index)
  {       
    if(root == null)return;  
    int preData = root.data;
 
    // Since there is no ancestor for root node,
    // so we doesn't assign it's value as 1           
    if(index == -1)index = root.data;
    else  M[index][preData] = 1;   
 
    MatrixUtil(root.left, preData);
    MatrixUtil(root.right, preData);
  }
 
  static void Matrix(Node root)
  {
 
    // Call Func MatrixUtil
    MatrixUtil(root, -1);
 
    // Applying Transitive Closure for the given Matrix
    for(int i = 0; i < size; i++)
    {
      for (int j = 0; j < size; j++)
      {
        for(int k = 0; k < size; k++)
        {
          if(M[j][k] == 1)
            M[j][k] = 1;
          else if((M[j][i] == 1 && M[i][k] == 1))
            M[j][k] = 1;
        }
      }
 
    }
 
    // Printing Matrix
    printMatrix();   
  }
 
  /* Driver program to test above functions*/
  public static void main(String[] args)
  {
    Node root = newnode(5);
    root.left = newnode(1);
    root.right = newnode(2);
    root.left.left = newnode(0);
    root.left.right = newnode(4);
    root.right.left = newnode(3);
    Matrix(root);
  }
}
 
// This code is contributed by Rajput-Ji


Python3
# Python3 program to construct ancestor
# matrix for given tree.
size = 6
  
M = [[0 for j in range(size)]
        for i in range(size)]
 
# A binary tree node
class Node:
     
    def __init__(self, data):
         
        self.left = None
        self.right = None
        self.data = data
         
# Helper function to create a new node
def newnode(data):
 
    temp = Node(data)
     
    return temp
 
def printMatrix():
     
    for i in range(size):
        for j in range(size):
            print(M[i][j], end = ' ')
         
        print()    
  
# First PreOrder Traversal
def MatrixUtil(root, index):
     
    if (root == None):
        return
      
    preData = root.data
              
    # Since there is no ancestor for
    # root node, so we doesn't assign
    # it's value as 1           
    if (index == -1):
        index = root.data
    else:
        M[index][preData] = 1   
      
    MatrixUtil(root.left, preData)
    MatrixUtil(root.right, preData)
 
def Matrix(root):
     
    # Call Func MatrixUtil
    MatrixUtil(root, -1)
      
    # Applying Transitive Closure
    # for the given Matrix
    for i in range(size):
        for j in range(size):
            for k in range(size):
                M[j][k] = (M[j][k] or
                          (M[j][i] and
                           M[i][k]))
      
    # Printing Matrix
    printMatrix()
  
# Driver code
if __name__=="__main__":
     
    root = newnode(5)
    root.left = newnode(1)
    root.right = newnode(2)
    root.left.left = newnode(0)
    root.left.right = newnode(4)
    root.right.left = newnode(3)
  
    Matrix(root)
      
# This code is contributed by rutvik_56


C#
// C# program to conancestor matrix for
// given tree. 
using System;
class GFG
{
  static readonly int size = 6;
  static int [,]M = new int[size, size];
 
  /* A binary tree node */
  public
 
    class Node
    {
      public
 
        int data;
      public
 
        Node left, right;
    };
 
  /* Helper function to create a new node */
  static Node newnode(int data)
  {
    Node node = new Node();
    node.data = data;
    node.left = node.right = null;
    return (node);
  }
 
  static void printMatrix()
  {
    for(int i = 0; i < size; i++)
    {
      for(int j = 0; j < size; j++)
        Console.Write(M[i, j] + " ");
      Console.WriteLine();
    }       
  }
 
  // First PreOrder Traversal
  static void MatrixUtil(Node root, int index)
  {       
    if(root == null)
      return;  
    int preData = root.data;
 
    // Since there is no ancestor for root node,
    // so we doesn't assign it's value as 1           
    if(index == -1)index = root.data;
    else  M[index,preData] = 1;   
 
    MatrixUtil(root.left, preData);
    MatrixUtil(root.right, preData);
  }
 
  static void Matrix(Node root)
  {
 
    // Call Func MatrixUtil
    MatrixUtil(root, -1);
 
    // Applying Transitive Closure for the given Matrix
    for(int i = 0; i < size; i++)
    {
      for (int j = 0; j < size; j++)
      {
        for(int k = 0; k < size; k++)
        {
          if(M[j, k] == 1)
            M[j, k] = 1;
          else if((M[j, i] == 1 && M[i, k] == 1))
            M[j, k] = 1;
        }
      }
    }
 
    // Printing Matrix
    printMatrix();   
  }
 
  /* Driver code*/
  public static void Main(String[] args)
  {
    Node root = newnode(5);
    root.left = newnode(1);
    root.right = newnode(2);
    root.left.left = newnode(0);
    root.left.right = newnode(4);
    root.right.left = newnode(3);
    Matrix(root);
  }
}
 
// This code is contributed by Rajput-Ji


Javascript


输出:

0 0 0 0 0 0 
1 0 0 0 1 0 
0 0 0 1 0 0 
0 0 0 0 0 0 
0 0 0 0 0 0 
1 1 1 1 1 0

上述解决方案的时间复杂度为 O(n 2 )。

方法二
此方法不使用任何辅助空间将值存储在向量中。创建一个给定大小的二维矩阵(比如 M)。现在的想法是在 PreOrder 中遍历树。遍历时,跟踪最后一个祖先。
当我们访问一个节点时,如果该节点为NULL返回,否则赋值M[lastAncestorValue][currentNodeValue]=1。
通过这个,我们得到了跟踪最低祖先的 Matrix(M),现在通过对这个 Matrix(M) 应用传递闭包,我们得到了所需的结果。

下面是上述思想的实现。

C++

// C++ program to construct ancestor matrix for
// given tree.
#include
using namespace std;
#define size 6
 
int M[size][size]={0};
 
/* A binary tree node */
struct Node
{
    int data;
    Node *left, *right;
};
 
/* Helper function to create a new node */
Node* newnode(int data)
{
    Node* node = new Node;
    node->data = data;
    node->left = node->right = NULL;
    return (node);
}
 
void printMatrix(){
        for(int i=0;idata;
             
        //Since there is no ancestor for root node,
        // so we doesn't assign it's value as 1           
        if(index==-1)index=root->data;
        else  M[index][preData]=1;   
     
    MatrixUtil(root->left,preData);
    MatrixUtil(root->right,preData);
}
 
void Matrix(Node *root){
    // Call Func MatrixUtil
    MatrixUtil(root,-1);
     
     
    //Applying Transitive Closure for the given Matrix
    for(int i=0;ileft     = newnode(1);
    root->right     = newnode(2);
    root->left->left = newnode(0);
    root->left->right = newnode(4);
    root->right->left = newnode(3);
 
    Matrix(root);
     
 
    return 0;
}

Java

// Java program to conancestor matrix for
// given tree. 
import java.util.*;
class GFG
{
  static final int size = 6;
 
  static int [][]M = new int[size][size];
 
  /* A binary tree node */
  static class Node
  {
    int data;
    Node left, right;
  };
 
  /* Helper function to create a new node */
  static Node newnode(int data)
  {
    Node node = new Node();
    node.data = data;
    node.left = node.right = null;
    return (node);
  }
 
  static void printMatrix()
  {
    for(int i = 0; i < size; i++)
    {
      for(int j = 0; j < size; j++)
        System.out.print(M[i][j] + " ");
      System.out.println();
    }       
  }
 
  // First PreOrder Traversal
  static void MatrixUtil(Node root, int index)
  {       
    if(root == null)return;  
    int preData = root.data;
 
    // Since there is no ancestor for root node,
    // so we doesn't assign it's value as 1           
    if(index == -1)index = root.data;
    else  M[index][preData] = 1;   
 
    MatrixUtil(root.left, preData);
    MatrixUtil(root.right, preData);
  }
 
  static void Matrix(Node root)
  {
 
    // Call Func MatrixUtil
    MatrixUtil(root, -1);
 
    // Applying Transitive Closure for the given Matrix
    for(int i = 0; i < size; i++)
    {
      for (int j = 0; j < size; j++)
      {
        for(int k = 0; k < size; k++)
        {
          if(M[j][k] == 1)
            M[j][k] = 1;
          else if((M[j][i] == 1 && M[i][k] == 1))
            M[j][k] = 1;
        }
      }
 
    }
 
    // Printing Matrix
    printMatrix();   
  }
 
  /* Driver program to test above functions*/
  public static void main(String[] args)
  {
    Node root = newnode(5);
    root.left = newnode(1);
    root.right = newnode(2);
    root.left.left = newnode(0);
    root.left.right = newnode(4);
    root.right.left = newnode(3);
    Matrix(root);
  }
}
 
// This code is contributed by Rajput-Ji

Python3

# Python3 program to construct ancestor
# matrix for given tree.
size = 6
  
M = [[0 for j in range(size)]
        for i in range(size)]
 
# A binary tree node
class Node:
     
    def __init__(self, data):
         
        self.left = None
        self.right = None
        self.data = data
         
# Helper function to create a new node
def newnode(data):
 
    temp = Node(data)
     
    return temp
 
def printMatrix():
     
    for i in range(size):
        for j in range(size):
            print(M[i][j], end = ' ')
         
        print()    
  
# First PreOrder Traversal
def MatrixUtil(root, index):
     
    if (root == None):
        return
      
    preData = root.data
              
    # Since there is no ancestor for
    # root node, so we doesn't assign
    # it's value as 1           
    if (index == -1):
        index = root.data
    else:
        M[index][preData] = 1   
      
    MatrixUtil(root.left, preData)
    MatrixUtil(root.right, preData)
 
def Matrix(root):
     
    # Call Func MatrixUtil
    MatrixUtil(root, -1)
      
    # Applying Transitive Closure
    # for the given Matrix
    for i in range(size):
        for j in range(size):
            for k in range(size):
                M[j][k] = (M[j][k] or
                          (M[j][i] and
                           M[i][k]))
      
    # Printing Matrix
    printMatrix()
  
# Driver code
if __name__=="__main__":
     
    root = newnode(5)
    root.left = newnode(1)
    root.right = newnode(2)
    root.left.left = newnode(0)
    root.left.right = newnode(4)
    root.right.left = newnode(3)
  
    Matrix(root)
      
# This code is contributed by rutvik_56

C#

// C# program to conancestor matrix for
// given tree. 
using System;
class GFG
{
  static readonly int size = 6;
  static int [,]M = new int[size, size];
 
  /* A binary tree node */
  public
 
    class Node
    {
      public
 
        int data;
      public
 
        Node left, right;
    };
 
  /* Helper function to create a new node */
  static Node newnode(int data)
  {
    Node node = new Node();
    node.data = data;
    node.left = node.right = null;
    return (node);
  }
 
  static void printMatrix()
  {
    for(int i = 0; i < size; i++)
    {
      for(int j = 0; j < size; j++)
        Console.Write(M[i, j] + " ");
      Console.WriteLine();
    }       
  }
 
  // First PreOrder Traversal
  static void MatrixUtil(Node root, int index)
  {       
    if(root == null)
      return;  
    int preData = root.data;
 
    // Since there is no ancestor for root node,
    // so we doesn't assign it's value as 1           
    if(index == -1)index = root.data;
    else  M[index,preData] = 1;   
 
    MatrixUtil(root.left, preData);
    MatrixUtil(root.right, preData);
  }
 
  static void Matrix(Node root)
  {
 
    // Call Func MatrixUtil
    MatrixUtil(root, -1);
 
    // Applying Transitive Closure for the given Matrix
    for(int i = 0; i < size; i++)
    {
      for (int j = 0; j < size; j++)
      {
        for(int k = 0; k < size; k++)
        {
          if(M[j, k] == 1)
            M[j, k] = 1;
          else if((M[j, i] == 1 && M[i, k] == 1))
            M[j, k] = 1;
        }
      }
    }
 
    // Printing Matrix
    printMatrix();   
  }
 
  /* Driver code*/
  public static void Main(String[] args)
  {
    Node root = newnode(5);
    root.left = newnode(1);
    root.right = newnode(2);
    root.left.left = newnode(0);
    root.left.right = newnode(4);
    root.right.left = newnode(3);
    Matrix(root);
  }
}
 
// This code is contributed by Rajput-Ji

Javascript


输出:

0 0 0 0 0 0 
1 0 0 0 1 0 
0 0 0 1 0 0 
0 0 0 0 0 0 
0 0 0 0 0 0 
1 1 1 1 1 0

如何逆向——从祖先矩阵构造树?
从祖先矩阵构造树