除了生成Fibonacci序列之外,递归的一个很好的例子是什么?

时间:2011-02-09 12:55:51

标签: c++ algorithm recursion fibonacci

  

可能重复:
  Real-world examples of recursion
  Examples of Recursive functions

我看到大多数编程语言教程通过使用一个简单的例子来教授递归,这个例子是如何生成斐波纳契序列,我的问题是,除了生成斐波那契序列以解释递归是如何工作之外还有另一个很好的例子吗?

23 个答案:

答案 0 :(得分:37)

经典是二叉树搜索:

def findval (node,val):
    if node == null:
        return null
    if node.val = val:
        return node
    if node.val > val:
        return findval (node.left,val)
    return findval (node.right,val)

findval (root,thing_to_find)

这可能比简单的公式稍微复杂一点,但它是递归的“面包和黄油”使用,它说明了使用它的最佳位置,即递归水平最小化的地方。

我的意思是:你可以添加两个非负数:

def add (a,b):
    if b == 0:
        return a
    return add (a+1,b-1)

但是你会发现自己很快就会耗尽大量的数据(除非编译器优化尾端递归,当然,你应该忽略那些你所关心的教学水平)。 / p>

答案 1 :(得分:28)

其他答案提到各种算法,这是完全正常的,但如果你想要更具体的“具体”示例,你可以列出某些目录及其子目录中的所有文件。分层文件系统是一个众所周知的递归(树)结构示例,您可以使用此具体示例显示深度优先和广度优先搜索。

答案 2 :(得分:25)

我最喜欢的递归示例是Towers of Hanoi:要将一堆碎片从极A移动到极点B,您将最低部分上方的所有部分移动到不是A或B的极点,然后移动最低部分然后你把你放在“帮手杆”上的堆叠移到最下面的一块上。对于第一步和第三步,您将递归地遵循此指令。请参阅链接以获得更长的解释:)

答案 3 :(得分:20)

检查palyndrome

bool recursivePalindrome(std::string str, unsigned int index = 0) {
    if (index > str.length()/2) return true;
    else if (str[index] == str[str.length()-index-1])
        return recursivePalindrome(str, ++index);
    else return false;
}

或者不太严肃的说明:))

void StackOverflow()
{
   StackOverflow();
}

答案 4 :(得分:15)

如何找到阶乘。

int GetFactorial(int n )
{
  if ( n==0) return 1;
  return n*GetFactorial(n-1);
}

这个想法是,因子被递归地定义为n和(n-1)的阶乘的乘积。从递归定义,你得到你的递归。

答案 5 :(得分:12)

遍历目录树的文件夹层次结构作为文件系统的一部分是一个很好的现实世界的例子。查看此SO帖子以获取C ++示例:

Why am I having problems recursively deleting directories?

答案 6 :(得分:10)

  • 这里给出的大多数其他例子都是数学例子,它们只是重新说明了相同的递归应用。
  • 搜索和排序变体是很好的算法示例,但对于初学者来说往往有点过于复杂。
  • 河内的塔楼是一个经典但非常做人的。

=====

我用来演示递归的简单功能的例子是目录树中的递归文件处理。

这是一个C#示例

void ProcessFiles( string sFolder )
{
    foreach( string f in Directory.GetFiles( sFolder ) )
    {
        DoSomethingTo( f );
    }
    foreach( string d in Directory.GetDirectories( sFolder ))
    {
        ProcessFiles( d );
    }
}

答案 7 :(得分:10)

合并排序是一种非常好的算法示例,它在递归实现时更易于阅读和理解。

这是Merge Sort的一个高级伪代码版本:

def merge_sort(List sortlist)
    if sortlist.length <= 1 return sortlist
    split sortlist into leftlist and rightlist
    return merge(merge_sort(leftlist), merge_sort(rightlist))   

def merge(List leftlist, List rightlist)
    while(leftlist and rightlist not empty)
        compare leftlist.first to rightlist.first
        pop lowest value off its list and append to resultlist
    append any remains of leftlist onto resultlist
    append any remains of rightlist onto resultlist
    return resultlist

编写和可视化的迭代版本要复杂得多。

答案 8 :(得分:5)

递归的好例子通常与底层数据结构或问题本身是递归的情况有关:树,图,使用分而治之法的算法(如许多种类),递归语法的解析器(如常见的算术表达式),找到类似国际象棋的两个玩家游戏的战略(一个简单的例子考虑Nim),组合问题等。

答案 9 :(得分:5)

有几个样本:

Catalan numbers

T(n) = Sum(T(i)*T(n-i)) for all 1 <= i < n

Ackermann function

A(x,y) = y+1 (if x = 0)
A(x,y) = A(x-1,1) (if y=0)
A(x,y) = A(x-1, A(x,y-1)) otherwise.

Simple Maze problem

Finding Hamiltonian Path problem

阶乘。

您可以在wiki页面看到其他参考资料。

答案 10 :(得分:3)

算术表达式的评估可以使用堆栈递归地或迭代地完成。比较这两种方法可能非常有益。

答案 11 :(得分:3)

尝试递归二进制搜索: http://www.fredosaurus.com/notes-cpp/algorithms/searching/rbinarysearch.html

或递归快速排序: http://www.dreamincode.net/forums/topic/72311-recursive-quicksort-algorithm/

在广泛的递归函数世界中,这只是两个小例子。

答案 12 :(得分:1)

我的婆婆在C学习了一个入门课程。她有一个家庭作业问题,如:

  

你有一个金属条(长度为len)和一个数字   (n)将金属切割成的   各种长度。你想要最大化   使用的金属量,但   不能超过总长度。

教师建议以二进制方式从1到2 ** n进行迭代,如果其对应位为0则排除顺序,如果其位为1则包括顺序,同时跟踪最大总和。他的提议将以多项式时间运行。

使用递归knapsack algorithm存在另一种解决方案。你可以从len迭代到1并进行深度优先搜索,以递归方式找到长度之和。

我使用递归的另一个区域是Huffman coding(用于压缩字符串),但这并没有背包问题的直观感觉。

递归是一个完全不同的奇妙概念。最好的学习或教学愿望。

答案 13 :(得分:1)

阿克曼功能:

/* undefined if m and n are negative */
uint32 ackermann( uint32 m, uint32 n )
{
  if( m < 0 && n < 0 ) { exit(1); /* invalid m and n */ }

  if( m == 0 ){ return n + 1; }

  if( m > 0 && n == 0 ){ return ackermann( m - 1, 1 ); }

  if( m > 0 && n > 0 ){ return ackermann( m - 1, ackermann(m, n - 1) ); }
}

m的多重比较&gt; 0是冗余的(可以简化)。然而,将它们保留为原样显示了Ackermann函数的标准定义。

但是,除了Fibonnaci数字之外,人们不必走近数学边缘就能找到有趣的递归函数。

您拥有最大的公分母(GDC)函数,快速排序和始终典型的二进制搜索算法。

答案 14 :(得分:1)

任何具有层次结构的东西。 例如,列出老板下面的所有员工。

答案 15 :(得分:1)

递归在数学归纳中找到它的基础,应该这样教。

通过列表处理可以清楚地显示通过归纳定义功能。例如,关于fold,有很多事情要说。

然后,继续前往树木。

答案 16 :(得分:1)

显然,这不是C ++,但概念是合理的:

PHP以递归方式遍历嵌套的多维数组:

public function recurse_me($collection) {
    foreach ($collection as $value) {
        if (is_array($value)) {
            $this->recurse_me($value);
        } else {
            // process value.
        }
    }
}

答案 17 :(得分:1)

我记得我通过编写一个搜索word ladders的程序来理解递归。在给定的字典中。

答案 18 :(得分:0)

学术范例是阶乘

  

N!

calculum。 在现实生活中,你会得到数学文章。

答案 19 :(得分:0)

堆排序也是一个很好的例子。你可以在Cormen,Rivest等人的“算法导论”中读到它。好书,我希望你会在那里找到很多有趣的东西。

答案 20 :(得分:0)

答案 21 :(得分:0)

有依赖递归的排序算法。

然后,通过递归实现二进制搜索

答案 22 :(得分:0)

对链接节点类型结构的大量操作可以是递归的。其他人提到了BST,但是如果你不想解释它们是什么,可以考虑在线性,未排序的列表中搜索最高值:

int MaxValue(Node node)
{
    if (node == null)
        return 0;

    if (node.Next == null)
        return node.Value;

    int maxNext = MaxValue(node.Next);
    return node.Value > maxNext ? node.Value : maxNext;
}

列表(在这种情况下,链接列表)很容易用现实世界的术语来解释;您的观众甚至不必拥有编程背景。您可以简单地将其描述为一组未分类的框或数字列表。