试图理解两个相同的方法调用如何在递归方法中一个接一个地放置

时间:2017-04-12 07:05:37

标签: recursion quicksort method-call

以下是quicksort的示例。我想知道在快速排序方法中两个递归方法调用是如何工作的,即它将以什么顺序执行?所以要检查我在每个方法之后放置syso的顺序(检查输出)。我怀疑为什么这个序列?因此它取决于任何条件?如果是这样,有什么条件?如果详细解释逻辑将会有所帮助。 提前谢谢你:)

void quicksort(int a[], int p, int r)    
{
    if(p < r)
    {
        int q;
        q = partition(a, p, r);
        System.out.println("q:"+q);
        quicksort(a, p, q);
        System.out.println("1");
        quicksort(a, q+1, r);
        System.out.println("2");
    }
}

int partition(int a[], int p, int r)
{
    System.out.println("p:"+p+" r:"+r);
    int i, j, pivot, temp;
    pivot = a[p];
    i = p;
    j = r;
    while(1)
    {
        while(a[i] < pivot && a[i] != pivot)
        i++;
        while(a[j] > pivot && a[j] != pivot)
        j--;
        if(i < j)
        {
            temp = a[i];
            a[i] = a[j];
            a[j] = temp;
        }
        else
        {
            return j;
        }
    }
}

输出

p:0 r:7
q:4
p:0 r:4
q:0
1
p:1 r:4
q:1
1
p:2 r:4
q:3
p:2 r:3
q:2
1
2
1
2
2
2
1
p:5 r:7
q:7
p:5 r:7
q:6
p:5 r:6
q:5
1
2
1
2
1
2
2

想知道为什么方法调用之间的差距?即println(放置在方法调用之后)语句如何执行而没有执行方法调用?

1 个答案:

答案 0 :(得分:0)

是的,这取决于条件:具体而言,每次通话时 p r 的值。排序的每个实例将按顺序执行两个调用:执行分支的 none 将进入第二个调用,直到完全完成该分支的第一次调用。

如果在显示参数值的函数顶部放置 println ,您将获得更好的跟踪。在计算 q 的值之后,您可能还想放置一个。试试看,看看它是否会告诉你故事的其余部分。

好的,你已经完成了印刷......你没有看到这种差距的原因?当您到达输出行“q:2”时,您已经五次调用 quicksort ,并且通过该序列的唯一进展是您已经完成了超过其中两个的“1”打印(你在第二次通话中)。就p和r而言,您当前的堆栈如下所示:

2, 3
2, 4
0, 4
0, 7

这是阵列左半部分(第二季度)的右半部分,深度为四级。您现在必须完成这些调用,这将使您获得“右半”打印的“1”打印,每个打印的“2”打印。

从另一个角度来看,您可以将阵列分解为单个元素。在执行此操作时,您会堆叠较小分区的调用。任何至少包含两个元素的调用都必须在返回到下一个打印之前完成其两个分区。

一旦你进入单元素阵列,你立即返回,然后打印下一个“1”或“2”。如果另一个分区也完全雾化,那么你可以进入下一个“1”或“2”,而不需要再进行分区调用。

中途,你到了你已完全雾化阵列左半部分的地方;当你清除所有出色的处理,备份堆栈,并完成所有打印时。然后你重复右半部分,并获得类似的效果。

我认为如果你给自己一个完整的痕迹,你可能会更容易理解。您可以在调试器中执行此操作,或者修改并添加打印语句,以便(1)您为每一行提供唯一且易于读取的输出,而不是每行“1”和“2”的8行,您无法分辨开; (2)您还可以从每个例程中跟踪 return 。这里的目标是能够识别您在每个输出线的过程中的位置。

是的,能够打印出诸如

之类的东西是另一个编程问题
1.L.R.R
1.1.2
(0,4) L
...

......或者您认为可读的任何格式。