Quicksort算法中的递归如何工作?

时间:2017-01-19 08:12:19

标签: algorithm sorting quicksort

我在谷歌看到一些像这样实现Quicksort算法的代码。

static public void QuickSort_Recursive(int [] arr, int left, int right)
{
    // For Recusrion
    if(left < right)
    {
        int pivot = Partition(arr, left, right);

        if(pivot > 1)
            QuickSort_Recursive(arr, left, pivot - 1);

        if(pivot + 1 < right)
            QuickSort_Recursive(arr, pivot + 1, right);
    }
}

我试图解决这个问题,我已经理解了代码本身是如何工作的,但有一点我感到困惑。递归(上面的代码)如何工作。如何终止。我是递归函数的新手,我只知道它的基本功能。

有人可以直截了当地向我解释并简单解释。 :)

P.S:我知道分区部分所以我没有包含它。

2 个答案:

答案 0 :(得分:1)

正如您可能知道的那样,递归的工作方式是根据较小的实例定义较大的问题,并通过解决较小的问题实例并使用这些解决方案构建更大的解决方案来解决更大的问题。

在您的情况下,检查left&lt;的if语句对是你问题的答案。由于Quicksort_recursive以递归方式减小问题的大小,因此数组中只有1个元素。然后,left将等于right,并且函数将不需要继续尝试递归地解决问题的较小实例。原因很简单:没有较小的问题实例。换句话说,没有非空子数组来排序,其大小小于1。

答案 1 :(得分:0)

在顺序方面,每个递归调用将所有局部变量(包括函数参数)和当前代码位置推送到堆栈(调用堆栈),然后跳转到函数的开头,使用新参数。当调用结束时,它会弹出变量并从堆栈中返回地址,然后返回到调用的位置。

但理解递归的最佳方法实际上是尝试按顺序解决,而是将问题分解为部分。您可以通过将数组分成两部分对数组进行排序,然后对每个部分进行排序 - 除非部件的大小为1或0,以防止您停止并完成该部分(这是一件小事,少于2个元素始终排序)进一步分解。

执行有点像二叉树,其中叶子是子阵列大小为0或1的停止条件。

我建议像这样修改代码:

static public void QuickSort_Recursive(int [] arr, int left, int right) {
    QuickSort_Recursive(arr, left, right, 1);
}

static public void QuickSort_Recursive(int [] arr, int left, int right, int depth)
{
    System.out.println(String.format("%"+(depth*3)+"sleft=%d, right=%d", "", left, right));
    // For Recusrion
    if(left < right)
        {
            int pivot = Partition(arr, left, right);

            if(pivot > 1)
                QuickSort_Recursive(arr, left, pivot - 1, depth+1);

            if(pivot + 1 < right)
                QuickSort_Recursive(arr, pivot + 1, right, depth+1);
        }
}

这会在每次通话时打印出来,可以帮助您了解正在发生的事情。