📜  通过使用其DFS遍历的开始和结束时间来构造根树

📅  最后修改于: 2021-05-04 11:37:43             🧑  作者: Mango

给定Rooted树中可用的N个顶点的DFS遍历的开始和结束时间,任务是构造树(打印每个节点的父级)。
根节点的父级为0。

例子:

Input: Start[] = {2, 4, 1, 0, 3}, End[] = {3, 5, 4, 5, 4}
Output: 3 4 4 0 3
Given Tree is -:
                      4(0, 5)
                    /   \
              (1, 4)3     2(4, 5)
                 /  \    
           (2, 3)1    5(3, 4)
The root will always have start time = 0
processing a node takes 1 unit time but backtracking 
does not consume time, so the finishing time 
of two nodes can be the same.

Input: Start[] = {4, 3, 2, 1, 0}, End[] = {5, 5, 3, 3, 5}
Output: 2 5 4 5 0

方法:

  • 树的根是起始时间为零的顶点。
  • 现在,找到一个顶点的子代就足够了,这样我们就可以找到每个顶点的父代。
  • 将Identity [i]定义为以i开头的顶点的索引。
  • 由于Start [v]和End [v]是顶点v的开始和结束时间。v的第一个子代是Identity [Start [v] +1]和
    第(i + 1)是Identity [End [chv [i]]],其中chv [i]是v的第i个子代。
  • 以DFS方式遍历并更新每个节点的父节点。

下面是上述方法的实现:

C++
// C++ implementation of the approach
#include 
using namespace std;
  
int N;
  
// Function to find the parent of each node.
vector Restore_Tree(int Start[], int End[])
{
  
    // Storing index of vertex with starting
    // time Equal to i
    vector Identity(N,0);
  
  
    for (int i = 0; i < N; i++)
    {
        Identity[Start[i]] = i;
    }
  
    // Parent array
    vector parent(N,-1);
    int curr_parent = Identity[0];
  
    for (int j = 1; j < N; j++)
    {
  
        // Find the vertex with starting time j
        int child = Identity[j];
  
        // If end time of this child is greater than
        // (start time + 1), then we traverse down and
        // store curr_parent as the parent of child
        if (End[child] - j > 1)
        {
            parent[child] = curr_parent;
            curr_parent = child;
        }
  
        // Find the parent of current vertex
        // over iterating on the finish time
        else
            parent[child] = curr_parent;
  
        // Backtracking takes zero time
        while (End[child]== End[parent[child]])
        {
            child = parent[child];
            curr_parent = parent[child];
            if (curr_parent == Identity[0])
                break;
        }
    }
    for (int i = 0; i < N; i++)
        parent[i] += 1;
  
    // Return the parent array
    return parent;
}
  
// Driver Code
int main()
{
    N = 5;
  
    // Start and End time of DFS
    int Start[] = {2, 4, 1, 0, 3};
    int End[] = {3, 5, 4, 5, 4};
    vector a = Restore_Tree(Start, End);
  
    for(int ans:a)
        cout << ans << " ";
  
    return 0;
}
  
// This code is contributed by mohit kumar 29


Java
// Java implemenation of above approach
import java.util.Arrays;
  
class GFG 
{
      
static int N = 5;
  
// Function to find the parent of each node.
static int[] Restore_Tree(int []S, int []End)
{
  
    // Storing index of vertex with starting
    // time Equal to i
    int []Identity = new int[N]; 
  
    for(int i = 0; i < N; i++)
        Identity[S[i]] = i;
  
    // Parent array
    int []parent = new int[N];
    Arrays.fill(parent,-1);
    int curr_parent = Identity[0];
      
    for(int j = 1; j < N; j++)
    {
  
        // Find the vertex with starting time j
        int child = Identity[j];
  
        // If end time of this child is greater than 
        // (start time + 1), then we traverse down and 
        // store curr_parent as the parent of child
        if(End[child] - j > 1)
        {
            parent[child] = curr_parent;
            curr_parent = child;
        }
          
        // Find the parent of current vertex
        // over iterating on the finish time
        else{ 
            parent[child] = curr_parent;
  
            // Backtracking takes zero time
            while(parent[child]>-1 && End[child] == End[parent[child]])
            {
                child = parent[child];
                curr_parent = parent[child];
                if(curr_parent == Identity[0])
                    break;
            }
        }
    }
    for(int i = 0; i < N; i++)
        parent[i] += 1;
  
    // Return the parent array
    return parent;
}
  
// Driver Code 
public static void main(String[] args) 
{
    // Start and End time of DFS
    int []Start = {2, 4, 1, 0, 3};
    int []End = {3, 5, 4, 5, 4};
    int ans[] =Restore_Tree(Start, End);
    for(int a:ans)
        System.out.print(a + " ");
}
}
  
// This code has been contributed by 29AjayKumar


Python
# Python implementation of the above approach
   
# Function to find the parent of each node.
def Restore_Tree(S, E):
   
    # Storing index of vertex with starting
    # time Equal to i
    Identity = N*[0]  
  
    for i in range(N):
        Identity[Start[i]] = i
   
    # Parent array
    parent = N*[-1]
    curr_parent = Identity[0]
      
    for j in range(1, N):
  
        # Find the vertex with starting time j
        child = Identity[j]
  
        # If end time of this child is greater than 
        # (start time + 1), then we traverse down and 
        # store curr_parent as the parent of child
        if End[child] - j > 1:
            parent[child] = curr_parent
            curr_parent = child
  
        # Find the parent of current vertex
        # over iterating on the finish time
        else:     
            parent[child] = curr_parent
  
            # Backtracking takes zero time
            while End[child]== End[parent[child]]:
                child = parent[child]
                curr_parent = parent[child]
                if curr_parent == Identity[0]:
                    break
    for i in range(N):
        parent[i]+= 1
   
    # Return the parent array
    return parent
   
# Driver Code 
if __name__=="__main__":
    N = 5
   
    # Start and End time of DFS
    Start = [2, 4, 1, 0, 3]
    End = [3, 5, 4, 5, 4]
    print(*Restore_Tree(Start, End))


C#
// C# implementation of the approach 
using System;
      
class GFG 
{
      
static int N = 5;
  
// Function to find the parent of each node.
static int[] Restore_Tree(int []S, int []End)
{
  
    // Storing index of vertex with starting
    // time Equal to i
    int []Identity = new int[N]; 
  
    for(int i = 0; i < N; i++)
        Identity[S[i]] = i;
  
    // Parent array
    int []parent = new int[N];
    for(int i = 0; i < N; i++)
        parent[i]=-1;
    int curr_parent = Identity[0];
      
    for(int j = 1; j < N; j++)
    {
  
        // Find the vertex with starting time j
        int child = Identity[j];
  
        // If end time of this child is greater than 
        // (start time + 1), then we traverse down and 
        // store curr_parent as the parent of child
        if(End[child] - j > 1)
        {
            parent[child] = curr_parent;
            curr_parent = child;
        }
          
        // Find the parent of current vertex
        // over iterating on the finish time
        else
        { 
            parent[child] = curr_parent;
  
            // Backtracking takes zero time
            while(parent[child]>-1 && End[child] == End[parent[child]])
            {
                child = parent[child];
                curr_parent = parent[child];
                if(curr_parent == Identity[0])
                    break;
            }
        }
    }
    for(int i = 0; i < N; i++)
        parent[i] += 1;
  
    // Return the parent array
    return parent;
}
  
// Driver Code 
public static void Main(String[] args) 
{
    // Start and End time of DFS
    int []Start = {2, 4, 1, 0, 3};
    int []End = {3, 5, 4, 5, 4};
    int []ans =Restore_Tree(Start, End);
    foreach(int a in ans)
        Console.Write(a + " ");
}
}
  
/* This code contributed by PrinciRaj1992 */


输出:
3 4 4 0 3

时间复杂度: O(N)
其中N是树中的节点数。