Algorithm 查找每个节点的大小

Algorithm 查找每个节点的大小,algorithm,recursion,graph,Algorithm,Recursion,Graph,我在1上有一棵树,我需要找到每个节点的大小。 我使用这个递归调用是为了 find_size(int curr , int parent){ S[curr]=1 for(int j:Children[curr]){ if(j==parent) continue; find_size(j,curr) S[curr]+=S[j]; } } 如何使用堆栈或其他方法将我

我在
1
上有一棵树,我需要找到每个节点的大小。 我使用这个递归调用是为了

find_size(int curr , int parent){
       S[curr]=1
       for(int j:Children[curr]){

               if(j==parent) continue;
                find_size(j,curr)
                S[curr]+=S[j];
     }

}

如何使用堆栈或其他方法将我的解决方案简化为非递归的解决方案?由于递归解决方案不适用于大型数据集。

我将描述一种可能的迭代方法,包括两个步骤:

  • 使用队列确定每个节点的深度
  • 按深度递减顺序处理节点
  • 这种方法基于树的遍历,因此它不直接模拟递归完成的遍历,并且具有易于迭代实现的优点


    对于步骤1:

    • 最初,只将根节点添加到队列中,并用depth=0标记它
    • 当队列不为空时,从队列中提取第一个节点,查看其深度(此处表示为
      currentDepth
      ),并通过使用
      childDepth
      =
      currentDepth
      +1标记每个节点,将其子节点添加到队列的末尾
    对于步骤2:

    • 按相反的深度顺序处理节点。节点的处理包括计算其子树大小,方法是将所有子节点的大小相加(当前节点加1)
    • 请注意,每次处理一个节点时,子节点都已被处理(因为所有深度更高的节点都已被处理),因此我们已经知道子子树的大小

    备注:

    对于步骤2,通过使用一个我们从未从中实际删除元素的列表(例如,可以使用指针保持队列头,并且在轮询时只能增加该指针)实现步骤1中的队列,可以有效地按深度递减顺序对节点进行排序

    以相反的顺序处理此列表是以递减的深度顺序遍历节点所需的全部。因此,实际上没有必要显式使用
    深度
    字段


    上述想法的实施情况如下所示:

    void find_size(){
    //第一步
    int队列[节点];
    队列[0]=1;//在队列中添加根
    int start=0;
    int-end=1;
    while(开始<结束){
    int node=queue[start++];//从队列中轮询一个节点
    对于(int i:Children[node]){//将其子项添加到末尾
    队列[end++]=i;
    }
    }
    //步骤2
    对于(int i=end-1;i>=0;i--){
    int节点=队列[i];
    S[node]=1;
    for(int j:子节点[节点]){
    S[node]+=S[j];
    }
    }
    }
    
    您通过索引来表示节点,因此我猜您将它们表示为两个数组,如下所示:

    int[]父项;//父项索引(根的父项为负,例如-1)
    int[][]子项;//每个节点的子节点索引
    
    您可以从叶节点开始收集和,并在知道所有子节点O(n)的结果后立即向上进行:

    s=newint[parent.length];
    int[]已处理=新int[parent.length];//正在处理的子级数
    for(int i=0;i=0&&processed[j]==children[j].length){//所有子项都被处理
    s[p]+=s[j];//调整家长分数
    已处理的[p]+;//增加父节点的已处理子节点数
    j=p;//父节点成为当前节点
    p=parent[j];//其父对象为父对象
    }
    }
    }
    
    但是时间竞争性是
    O(N*N)
    @NarendraModi它是O(N),编辑了答案,对根的检查丢失了。它在返回时模仿DFS的第二部分(因此从叶子而不是根开始),节点将以完全相同的顺序处理。