I'm studying basic array sorting and am struggling just a little bit to fully understand it's logic. I understand the recursion, meaning splitting an array to two arrays on each side of a pivot, and then continuing partitioning each of these sub-arrays until an array of just one element is reached.
What I don't always completely understand is the implementation of the while loop itself.

http://www.vogella.com/tutorials/JavaAlgorithmsQuicksort/article.html

Here I've encountered an implementation that chooses the middle element as the pivot. I understand the pivot can be any element, whether it's the first, last, any random element or an element specifically chosen for maximum efficiency.
With the middle element as pivot for some reason I find it more intuitive to understand.

```
while (i <= j) {
// If the current value from the left list is smaller than the pivot
// element then get the next element from the left list
while (numbers[i] < pivot) {
i++;
}
// If the current value from the right list is larger than the pivot
// element then get the next element from the right list
while (numbers[j] > pivot) {
j--;
}
// If we have found a value in the left list which is larger than
// the pivot element and if we have found a value in the right list
// which is smaller than the pivot element then we exchange the
// values.
// As we are done we can increase i and j
if (i <= j) {
exchange(i, j);
i++;
j--;
}
}
```

This is the relevant part.

1) Why do we increase i and decrease j only if the i element is smaller than the pivot or the j element is larger than the pivot? Why not also when it's equal?
If an element is equal to the pivot, it's fine where it is, since it doesn't matter which side of the pivot it ends up in, so why can't we move on increasing/decreasing?
I've tried doing it by the way and as I expected the end result wasn't sorted and I didn't understand what went wrong even after debugging step by step.

2) Am I right in saying that, excluding edge cases, upon exiting the external loop, i = j +1? Always? And that one of these elements, i or j, has the value of the pivot we used? But which one and why?

```
// Recursion
if (low < j)
quicksort(low, j);
if (i < high)
quicksort(i, high);
```

3) What I would have expected here, instead of passing on low to j and i to high,
is:
assuming pivotIndex is the index of the pivot after the loop ends,

```
quicksort(low, pivotIndex - 1);
quicksort(pivotIndex + 1, high);
```

because pivotIndex is right where the pivot should be, it's his final position.
So I would love an explanation for that too, please.

Thank you.