📜  使用 DFS 的树中所有节点的子树

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

使用 DFS 的树中所有节点的子树

给定树的 n 个节点及其连接,打印每个节点的子树节点。
节点的子定义为作为节点的子节点的树。该名称强调了作为树节点后代的所有事物也是树,并且是较大树的子集。

例子 :

Input: N = 5
  0 1
  1 2
  0 3
  3 4
Output: 
Subtree of node 0 is 1 2 3 4 
Subtree of node 1 is 2 
Subtree of node 3 is 4

Input: N = 7
  0 1
  1 2
  2 3
  0 4
  4 5
  4 6
Output:
Subtree of node 0 is 1 2 3 4 5 6 
Subtree of node 1 is 2 3 
Subtree of node 4 is 5 6 

方法:对每个节点进行 DFS 遍历并打印从特定节点可到达的所有节点。
下面代码的解释:

  1. 函数dfs(0, 0) 时,start[0] = 0, dfs_order.push_back(0),visited[0] = 1 以跟踪 dfs 顺序。
  2. 现在,考虑邻接表(adj[100001]),因为考虑到连接到节点 0 的有向路径元素将在与节点 0 对应的邻接表中。
  3. 现在,递归调用 dfs函数,直到遍历 adj[0] 的所有元素。
  4. 现在,dfs(1, 2) 被调用,现在 start[1] = 1, dfs_order.push_back(1),visited[1] = 1 在 adj[1] 元素被遍历之后。
  5. 现在遍历 adj [1],其中仅包含节点 2,当遍历 adj[2] 时它不包含任何元素,它将中断并且 end[1]=2。
  6. 同样,遍历所有节点并将 dfs_order 存储在数组中以查找节点的子树。

C++
// C++ code to print subtree of all nodes
#include
using namespace std;
 
// arrays for keeping position
// at each dfs traversal for each node
int start[100001];
int end[100001];
 
// Storing dfs order
vectordfs_order;
vectoradj[100001];
int visited[100001];
 
// Recursive function for dfs
// traversal dfsUtil()
void dfs(int a,int &b)
{
 
    // keep track of node visited
    visited[a]=1;
    b++;
    start[a]=b;
    dfs_order.push_back(a);
     
    for(vector:: iterator it=adj[a].begin();
                           it!=adj[a].end();it++)
    {
        if(!visited[*it])
        {
            dfs(*it,b);
        }
    }
    endd[a]=b;
}
 
// Function to print the subtree nodes
void Print(int n)
{
    for(int i = 0; i < n; i++)
    {
        // if node is leaf node
        // start[i] is equals to endd[i]
        if(start[i]!=endd[i])
        {
            cout<<"subtree of node "<


Java
// Java code to print subtree of all nodes
import java.util.*;
public class Main
{
    // arrays for keeping position
    // at each dfs traversal for each node
    static int[] start = new int[100001];
    static int[] end = new int[100001];
   
    // Storing dfs order
    static Vector dfs_order = new Vector();
    static Vector> adj = new Vector>();
    static boolean[] visited = new boolean[100001];
       
    // Recursive function for dfs traversal dfsUtil()
    static int dfs(int a, int b)
    {
        // keep track of node visited
        visited[a] = true;
        b += 1;
        start[a] = b;
        dfs_order.add(a);
   
        for(int it = 0; it < adj.get(a).size(); it++)
        {
            if(!visited[adj.get(a).get(it)])
                b = dfs(adj.get(a).get(it), b);
        }
   
        endd[a] = b;
        return b;
    }
       
    // Function to print the subtree nodes
    static void Print(int n)
    {
        for(int i = 0; i < n; i++)
        {
            // If node is leaf node
            // start[i] is equals to endd[i]
            if(start[i] != endd[i])
            {
                System.out.print("subtree of node "+ i + " is ");
                for(int j = start[i]+1; j < endd[i]+1; j++)
                {
                    System.out.print(dfs_order.get(j-1) +  " ");
                }
                System.out.println();
            }
        }
    }
     
    public static void main(String[] args) {
        // No of nodes n = 10
        int n =10, c = 0;
          
        for(int i = 0; i < 100001; i++)
        {
            adj.add(new Vector());
        }
           
        adj.get(0).add(1);
        adj.get(0).add(2);
        adj.get(0).add(3);
        adj.get(1).add(4);
        adj.get(1).add(5);
        adj.get(4).add(7);
        adj.get(4).add(8);
        adj.get(2).add(6);
        adj.get(6).add(9);
           
        // Calling dfs for node 0
        // Considering root node at 0
        dfs(0, c);
       
        // Print child nodes
        Print(n);
    }
}
 
// This code is contributed by divyeshrabadiya07.


Python3
# Python3 code to print subtree of all nodes
 
# arrays for keeping position at
# each dfs traversal for each node
start = [None] * 100001
end = [None] * 100001
 
# Storing dfs order
dfs_order = []
adj = [[] for i in range(100001)]
visited = [False] * 100001
 
# Recursive function for dfs traversal dfsUtil()
def dfs(a, b):
  
    # keep track of node visited
    visited[a] = 1
    b += 1
    start[a] = b
    dfs_order.append(a)
     
    for it in adj[a]:
        if not visited[it]:
            b = dfs(it, b)
      
    endd[a] = b
    return b
  
# Function to print the subtree nodes
def Print(n):
  
    for i in range(0, n):
      
        # If node is leaf node
        # start[i] is equals to endd[i]
        if start[i] != endd[i]:
          
            print("subtree of node", i, "is", end = " ")
            for j in range(start[i]+1, endd[i]+1):
              
                print(dfs_order[j-1], end = " ")
              
            print()
 
# Driver code
if __name__ == "__main__":
  
    # No of nodes n = 10
    n, c = 10, 0
     
    adj[0].append(1)
    adj[0].append(2)
    adj[0].append(3)
    adj[1].append(4)
    adj[1].append(5)
    adj[4].append(7)
    adj[4].append(8)
    adj[2].append(6)
    adj[6].append(9)
     
    # Calling dfs for node 0
    # Considering root node at 0
    dfs(0, c)
 
    # Print child nodes
    Print(n)
  
# This code is contributed by Rituraj Jain


C#
// C# code to print subtree of all nodes
using System;
using System.Collections.Generic;
class GFG {
     
    // arrays for keeping position
    // at each dfs traversal for each node
    static int[] start = new int[100001];
    static int[] end = new int[100001];
  
    // Storing dfs order
    static List dfs_order = new List();
    static List> adj = new List>();
    static bool[] visited = new bool[100001];
      
    // Recursive function for dfs traversal dfsUtil()
    static int dfs(int a, int b)
    {
        // keep track of node visited
        visited[a] = true;
        b += 1;
        start[a] = b;
        dfs_order.Add(a);
  
        for(int it = 0; it < adj[a].Count; it++)
        {
            if(!visited[adj[a][it]])
                b = dfs(adj[a][it], b);
        }
  
        endd[a] = b;
        return b;
    }
      
    // Function to print the subtree nodes
    static void Print(int n)
    {
        for(int i = 0; i < n; i++)
        {
            // If node is leaf node
            // start[i] is equals to endd[i]
            if(start[i] != endd[i])
            {
                Console.Write("subtree of node "+ i + " is ");
                for(int j = start[i]+1; j < endd[i]+1; j++)
                {
                    Console.Write(dfs_order[j-1] +  " ");
                }
                Console.WriteLine();
            }
        }
    }
     
  static void Main() {
    // No of nodes n = 10
    int n =10, c = 0;
     
    for(int i = 0; i < 100001; i++)
    {
        adj.Add(new List());
    }
      
    adj[0].Add(1);
    adj[0].Add(2);
    adj[0].Add(3);
    adj[1].Add(4);
    adj[1].Add(5);
    adj[4].Add(7);
    adj[4].Add(8);
    adj[2].Add(6);
    adj[6].Add(9);
      
    // Calling dfs for node 0
    // Considering root node at 0
    dfs(0, c);
  
    // Print child nodes
    Print(n);
  }
}
 
// This code is contributed by divyesh072019.


Javascript


输出:
subtree of node 0 is 1 4 7 8 5 2 6 9 3 
subtree of node 1 is 4 7 8 5 
subtree of node 2 is 6 9 
subtree of node 4 is 7 8 
subtree of node 6 is 9

时间复杂度: O(N ^ 2)
辅助空间: O(N)