从给定的二叉树构造祖先矩阵
给定一棵二叉树,其中所有值都从0到n-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
如何逆向——从祖先矩阵构造树?
从祖先矩阵构造树