为什么快速排序称为尾递归算法?

时间:2012-08-08 11:57:15

标签: algorithm complexity-theory time-complexity quicksort tail-recursion

我知道尾递归算法是written out in this SO answer。然而,我正在经历这个video of quick sort algorithm from MIT,并且在18:30秒,教授说这是尾递归算法。我无法连接这是如何尾递归。我们不是在递归的任何步骤进行计算,还是我们?你能解释为什么这被引用作尾递归算法的一个例子。请以我知道递归算法是什么为前提,给出答案。我不清楚的部分是为什么它被称为 tail 递归?

3 个答案:

答案 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()的两个分支部分,我们可以在具有较高项目的一侧使用尾递归(基于枢轴位置)。

enter image description here

答案 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)

递归函数的第一步是分区。然后,作为最后一步,您在两个分区上调用递归函数。

来自维基百科:

  

在计算机科学中,尾调用是发生的子程序调用   在另一个程序中作为最后的行动;它可能会产生回报   然后由调用过程立即返回的值。