Some Context and History
FrankW's post answers most of the question, but I can add some references and give some context to it.
First of all, the algorithm is named after Dijkstra because of his 1976 programming book “A Discipline of Programming”, wherein chapter 14 deals with the so-called “Dutch National Flag Problem (DNFP)”:
Rearrange an array of red, white and blue pebbles by swaps, such that their colors mimic the flag of the Netherlands.
The DNFP was intended as a programming exercise and is maybe not interesting per se.
What is often needed, however, is sorting an array, and this is often done using Quicksort (see this question if you are interested in why is quicksort better than other sorting algorithms in practice).
From flags to sorting
The crucial part in Quicksort is to partition an array around a pivot, i.e. rearrange the array to have small elements to the left, elements equal to the pivot in the middle and large elements to the right.
— exactly like in the DNFP!
Therefore, we can use the algorithms for the DNFP in the 3-way partitioning step for Quicksort.
Is this excessive swapping needed for the algorithm?
As the algorithm from FrankW's answer nicely demonstrates, the extra swapping is not needed.
Dijkstra gives an enhanced version of the algorithm in his book that avoids the extra swap, as well.
I suppose that Sedgewick used the version with the extra swap to keep the code concise — for educational reasons, so to say.
What is “Performance”?
Does it improve performance in some way? If it does improve performance, how?
If it doesn't affect performance, please give a proper explanation or a proof as to why this it does not affect performance.
Also, would the second method I mentioned affect performance in any way? please explain why.
First of all, performance depends on the input, especially the length of the array; but also on the number of elements equal to the pivot and so on.
To answer you question, you will have to fix an input model.
Secondly, it is not clear what exactly we mean by “performance” ...
If we are interested in total running time in seconds, then the answer will depend on the machine/processor you use, the compiler, potentially the Java Virtual Machine, the OS, other processes ...
There will not be a definite answer to the above questions then, but you might run some experiments on your machine.
For comparing two alternative algorithms, it might be enough to compare a coarser measure, like the number of executed instructions: If one algorithm needs much more instructions, it will (usually) also be slower.
Why Dijkstra's method is hardly used in practice
In the case of 3-way Quicksort, practical implementations (e.g. C++ standard library, Java 6 runtime library) use “fat partitioning”, a different partitioning scheme developed by Bentley and McIlroy (see their paper “Engineering a sort function”):
a = b = 0;
c = d = n-1;
for (;;) {
while (b <= c && A[b] <= v) {
if (A[b] == v) swap(A, a++, b);
b++;
}
while (c >= b && x[c] >= v) {
if (A[c] == v) swap(A, d--, c);
c--;
}
if (b > c) break;
swap(A,b++, c--);
}
s = min(a, b-a);
for(l = 0, h = b-s; s; s--) swap(A, l++, h++);
s = min(d-c, n-1-d);
for(l = b, h = n-s; s; s--) swap(A, l++, h++);
The invariant for the array is then
--------------------------
| = | < | ? | > | = |
--------------------------
i.e. equal elements are put to the extreme ends and have to be swapped to the middle again at the end.
This method does in fact more swaps for many equal elements than your optimized Dijkstra partitioning.
But it has almost no overhead for inputs without equal elements when compared to an optimized 2-way Quicksort; this is not the case for your algorithm: It would do roughly three times as many swaps on inputs without equal elements (see very similar computation here).
Dual-Pivot Quicksort
A second way how the DNFP can help in Quicksort is when we use two pivots instead of one. Then, each partitioning step rearranges the array such that small elements are left, elements between the two pivots go to the middle and large ones to the right.
You may find it interesting that the Java 7 runtime library uses dual-pivot Quicksort with a partitioning method that is essentially your algorithm from above!
gt
without putting anything at the tail of the array, you are not partitioning the array. Try your new algorithm on some example inputs to see if it really works. $\endgroup$