我知道尾递归算法是written out in this SO answer。然而,我正在经历这个video of quick sort algorithm from MIT,并且在18:30秒,教授说这是尾递归算法。我无法连接这是如何尾递归。我们不是在递归的任何步骤进行计算,还是我们?你能解释为什么这被引用作尾递归算法的一个例子。请以我知道递归算法是什么为前提,给出答案。我不清楚的部分是为什么它被称为 tail 递归?
答案 0 :(得分:7)
尾递归与步骤计算无关。它是关于“可以在不构建调用堆栈的情况下评估递归”。 What is tail recursion?给出的示例是一个特例。如果你更深入地看一下这个例子,你可以找到的是那个
def recsum(x):
if x==1:
return x
else:
return x+recsum(x-1)
1)要成功运行上面的代码,需要构建调用堆栈。但是,
def tailrecsum(x,running_total=0):
if x==0:
return running_total
else:
return tailrecsum(x-1,running_total+x)
2)运行上面的代码,你不需要因为running_total而构建调用堆栈。只需为“原始调用”和递归构建调用堆栈,无需构建调用堆栈,因为评估此函数所需的状态存储在running_total中。
而且,关于快速排序,我认为教授可能意味着可以通过“使用”尾部回归来优化快速排序。对于qsort()的两个分支部分,我们可以在具有较高项目的一侧使用尾递归(基于枢轴位置)。
答案 1 :(得分:4)
查看Quicksort的维基页面。有一个尾递归的版本
function quicksort(array, 'left', 'right')
// If the list has 2 or more items
if 'left' < 'right'
// See "Choice of pivot" section below for possible choices
choose any 'pivotIndex' such that 'left' ≤ 'pivotIndex' ≤ 'right'
// Get lists of bigger and smaller items and final position of pivot
'pivotNewIndex' := partition(array, 'left', 'right', 'pivotIndex')
// Recursively sort elements smaller than the pivot
quicksort(array, 'left', 'pivotNewIndex' - 1)
// Recursively sort elements at least as big as the pivot
quicksort(array, 'pivotNewIndex' + 1, 'right')
根据Tail recursion的定义,quicksort
的最后一个方法调用本身就是尾递归。但是其他一些实现并不是尾递归。
quicksort(left) + pivot + quicksort(right)
因为quicksort
中的最终操作是sorted_left + pivot + sorted_right
答案 2 :(得分:1)
递归函数的第一步是分区。然后,作为最后一步,您在两个分区上调用递归函数。
来自维基百科:
在计算机科学中,尾调用是发生的子程序调用 在另一个程序中作为最后的行动;它可能会产生回报 然后由调用过程立即返回的值。