【问题标题】:Binary Tree Recursive Function二叉树递归函数
【发布时间】:2012-10-29 01:09:17
【问题描述】:

我需要打印一个如下所示的二叉树:

--------x-------
----x-------x---
--x---x---x---x-
-x-x-x-x-x-x-x-x 
xxxxxxxxxxxxxxxx

使用递归打印除第一行外的行的左侧和右侧。所以该函数会调用一个显示函数,参数为左起点和右终点。然后它会调用自己两次,一次调用左侧,一次调用右侧。

    #include <stdio.h>

#define LENGTH 16

void makeBranches(int, int);
void display(int, int);

int main(){

  makeBranches(0, LENGTH-1);
}

void makeBranches(int left, int right){

  if(left >= right){
    return;
  } else{
    display(left, right);
      makeBranches(left, (right+left)/2);
      makeBranches((right+left)/2+1, right);  
  }
}

void display(int left, int right){
  int mid = (left+right)/2;
  int i;

  for(i = left; i <= right; i++){
    if(i == mid)
      printf("X");
    else
      printf("-");
  }

  if(right == LENGTH-1)
    printf("\n");

}

这就是我的代码目前的样子,尽管它已经更改了很多次。

我不知道如何让 makeBranches 的第一次调用执行,然后是第二次调用。现在它只做左边的调用,看起来像这样:

-------X--------
---X-----X--X-

【问题讨论】:

    标签: c recursion binary-tree


    【解决方案1】:

    你需要做一个breadth-first traversal

    【讨论】:

      【解决方案2】:

      正如您已经看到的,您的问题在于调用递归函数的结构树。为了防止这种行为,您需要实现一种设计,即在打印任何内容之前扫描整个树。

      您现在的调用结构如下所示:

      makeBranches(left,right) -> 
        makeBranches(left, (right+left)/2) ->
          makeBranches(left, ((right+left)/2+left)/2) ->
            makeBranches(left, (((right+left)/2+left)/2+left)/2) -> etc.
        makeBranches((right+left)/2+1,right) ->
          makeBranches((right+(right+left)/2+1)/2+1,right) ->
            makeBranches((right+(right+(right+(right+left)/2+1)/2+1)/2+1)/2+1,right) -> etc.
      

      为了解决这个问题,您的目标是在打印之前捕获每个级别。为此,您需要某种形式的集合,例如为每一侧添加链接列表,然后一旦扫描整个树,您就可以重建绘图。

      在您的 display 函数中,您已经创建了一个检查以了解这是行的左侧还是右侧:

      if(right == LENGTH-1)
          printf("\n");
      

      所以让我们修改显示调用。

      void display(int left, int right){
        int mid = (left+right)/2;
        int i;
        string thisLine = "";
      
        for(i = left; i <= right; i++){
          if(i == mid)
            thisLine += "X";
          else
            thisLine += "-";
        }
      
        if(right == LENGTH-1) {
          rightList.add(thisLine);
        } else {
          leftList.add(thisLine);
        }
      }
      

      现在,从您的main() 构建整个树后,打印出每个列表的每个节点,然后是left-&gt;right-&gt;"\n"(重复直到为空)。

      您需要注意的一些注意事项,但可以设计的是,您对display 的第一次调用会创建整行,因此如果您使用我的代码,它会将其放在right 列表中,这意味着您必须像 right-&gt;(left-&gt;right-&gt;"\n")repeat 那样绘制它

      这有意义吗?我希望我没有在概念上跳过任何内容:\

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2019-09-09
        • 2016-07-24
        • 1970-01-01
        • 2013-07-23
        • 1970-01-01
        • 2016-04-19
        • 2014-03-29
        相关资源
        最近更新 更多