2010-12-17 361 views
1

给定以下递归函数,将由神秘(4)打印什么?递归函数

void mysterious(int x) { 
    if (x == 0) return; 
    printf(“%d ”, x); 
    mysterious(x-1); 
    mysterious(x-1); 
} 

这里是我的调用堆栈:

mysterious(4) => print 4 
mysterious(3) => print 3 
mysterious(2) => print 2 
mysterious(1) => print 1 
mysterious(0) => print 0 

这是正确的吗?

+6

有人使用功能名称'mysterious'在其所有的考题? :) – sje397 2010-12-17 04:58:47

+1

对不起,你自己做的时间 – KevinDTimm 2010-12-17 05:01:36

+0

有什么神秘的吗?编译和运行比在SO上发布更困难吗? – ruslik 2010-12-17 05:08:32

回答

5

你为什么不直接用你选择的语言编辑一个编辑器,编译它并运行?我选择了Java,但,这只是因为我之间CygWin的我此刻的箱装我 - 我宁愿被用C :-)

public class testprog { 
    public static void mysterious(int x) { 
     if (x == 0) return; 
     System.out.print(x + " "); 
     mysterious(x-1); 
     mysterious(x-1); 
    } 
    public static void main(String args[]) { 
     mysterious(4); 
    } 
} 

它输出的数字:

4 3 2 1 1 2 1 1 3 2 1 1 2 1 1 

基本上,发生的事情是,在每个级别上,你打印出数字,然后用下一个最低数字两次调用下一个级别(除非达到零)。

旁白:从技术上说,你调用下一层与零,但是,因为它直接返回了,它没有对输出的影响。

下图有望说明这更好的,用不同的符号代表不同的层次:

(4) (-------------------------------) (-------------------------------) 
    {3} {-----------} {-----------} {3} {-----------} {-----------} 
      [2] [1] [1] [2] [1] [1]   [2] [1] [1] [2] [1] [1] 
+0

这很有道理。所以基本上,这是双重神秘的(x-1),导致下一个最低数字被调用两次? – kachilous 2010-12-17 05:20:33

+0

是的,它在一个! – paxdiablo 2010-12-17 05:26:34

1

号将不打印0原因时x==0它将返回

而且,由于你有

mysterious(x-1); 
mysterious(x-1); 

将打印(固定)

4 3 2 1 1 2 1 1 3 2 1 1 2 1 1 

mysterious(x-1);不会更改x的值。它只是再次调用mysterious(),这次与价值x-1

+0

什么是“返回”意思?没有随后的声明,我不习惯看到回报。 – kachilous 2010-12-17 04:58:06

+0

当处于无效函数(一个函数不返回值)时使用return函数退出函数并返回被调用函数 – Muggen 2010-12-17 04:59:03

+2

4 3 2 1 1 2 1 1 3 2 1 1 2 1 1 - 4只有一次,然后分支对于每个连续呼叫 – 2010-12-17 05:00:12

2

不,这将是

mysterious(4) => print 4 
mysterious(3) => print 3 
mysterious(2) => print 2 
mysterious(1) => print 1 
mysterious(1) => print 1 
mysterious(2) => print 2 
mysterious(1) => print 1 
mysterious(1) => print 1 
mysterious(3) => print 3 
mysterious(2) => print 2 
mysterious(1) => print 1 
mysterious(1) => print 1 
mysterious(2) => print 2 
mysterious(1) => print 1 
mysterious(1) => print 1 

因为0将导致函数返回较早并因为双呼叫。

7

因为每个函数调用都会依次产生2个函数调用,所以您可以将您的递归可视化为“树”,可以这么说,并且您正在树上进行前序遍历。

这将是这个样子:

      4 
          | 
       3----------+----------3 
       |      | 
      2----+----2   2----+----2 
      |   |   |   | 
     1--+--1 1--+--1  1--+--1 1--+--1 

执行的顺序,你已经是:

  • 打印数量
  • 呼叫与X-1
  • 通话功能带x-1的函数再次

这相当于我们的“树可视化”这样做:

  • 打印根
  • 遍历左节点
  • 遍历右节点

输出将是:

4 3 2 1 1 2 1 1 3 2 1 1 2 1 1 
+0

这就是我曾经的想法。它实际上不是将所有这些打印在一行上,每个数字之间只有一个空格?打印语句中没有新行'\ n'字符......这就是我认为会发生的事情 - 但我并没有使用C语言。 – jeremysawesome 2010-12-17 05:07:06

+0

@jeremyawesome,非常敏锐:)。我改变了输出。 – riwalk 2010-12-17 05:15:15