0

Below is an example of quicksort. I was wondering how two recursive method call inside quicksort method works i.e in what sequence it'll execute? So to check in what sequence I placed syso after each method (check output).My doubt why this sequence?Thus it depends on any conditions? if so, what condition? It would be helpful if explained the logic in detail. Thank you in advance :)

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;
        }
    }
}

Output

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

Would like to know why the gap between method calls?i.e how println(placed after method calls) statement getting executed w/o executing method call?

Shashank
  • 13
  • 7

1 Answers1

0

Yes, it depends on conditions: specifically, the values of p and r on each call. Each instance of the sort will do the two calls in order: none of the execution branches will get to the second call until the first call of that branch is completely done.

You will get a much nicer trace if you put a println at the top of the function that displays the parameter values. You might want to place one after you compute the value of q, as well. Try that, and see whether it tells you the rest of the story.


Okay, you've done the printing ... and you don't see the reason for that gap? When you get to the output line "q:2", you've made five calls to quicksort, and the only progress through that sequence is that you've made it past the "1" print for two of them (you're in the second call). Your current stack looks like this, in terms of p and r:

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

This is the right half of the left half (second quarter) of the array, four levels deep. You now have to finish off those calls, which will get you to the "1" print for the "right-half" ones, the "2" print for each of them.

Looking at it another way, you work to partition the array down to single elements. While you're doing this, you stack up calls for smaller partitions. Any call with at least two elements has to finish off both of its partitions before it returns to the next print.

Once you get to a single-element array, you return right away, and get to print the next "1" or "2". If the other partition is also fully atomized, then you get to the next "1" or "2" without any more partitioning calls.

Halfway through, you get to the point where you've fully atomized the left half of the array; that's when you clear out all the outstanding processing, back up the stack, and do all of that printing. Then you recur down the right half, and get a similar effect.

I think you might have an easier time understanding if you'd give yourself a full trace. Either follow this in your debugger, or modify and add print statements so that (1) you have a unique, easily-read output for every line, rather than 8 lines each of "1" and "2" that you can't tell apart; (2) you can also trace the return from each routine. The objective here is to be able to recognize where you are in the process at each output line.

Yes, it's another programming problem to be able to print out things such as

1.L.R.R
1.1.2
(0,4) L
...

... or whatever format you find readable.

Prune
  • 76,765
  • 14
  • 60
  • 81
  • Hi Prune placed println in following places : 1) static int partition(int a[], int p, int r){ system.out.println("p:"+p+" r:"+r); 2) 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"); – Shashank Apr 21 '17 at 12:33
  • Good for you. Did that clear up your understanding? – Prune Apr 21 '17 at 16:24
  • Hi prune i think u dint get full comment last time. Sry my wrong. PFB rest of comment. 2) static int partition(int a[], int p, int r) { println("p:"+p+" r:"+r); output : 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 why the gap between method calls?i.e how println(placed after method calls) statement getting executed w/o executing method call? – Shashank Apr 25 '17 at 10:42
  • Please edit your information updates into the original question. Here, they're far too hard to read. – Prune Apr 25 '17 at 17:23