The reason why your algorithm has been stated correctly by @RSahu, you are resetting the counter to 0 which means you can do as much as 1+2+...+n
iterations.
Here is a small example exhibiting linear time to process the array:
#include <iostream>
#include <array>
using namespace std;
int main() {
array<int,10> A{-1, 0, -1, 0, 1, 1, 0, 1, 0, -1};
int i=0,j=0, k=9;
while(j!=k) {
if(A[j] == 0) {
++j;
}
else if(A[j] == -1) {
swap(A[i], A[j]);
++i; ++j;
}
else {
swap(A[j], A[k]);
--k;
}
}
for(auto ai : A)
cout << ai << " ";
cout << endl;
}
You can see it live there.
How does it work ? We maintain three counters i
, j
and k
with the invariants that:
- all items in the range:
[0, i)
are -1
- all items in the range:
[i, j)
are 0
- all items in the range:
(k, n-1)
are +1
Where [
means an inclusive bound, and )
or (
means an exclusive bound.
Initially
i=j=0
and 'k=n-1`. The invariants are respected.
First case
if(A[j] == 0) {
++j;
}
The value of A[j]
is 0, so we can increment j
and the invariants still hold.
Second case
else if(A[j] == -1) {
swap(A[i], A[j]);
++i; ++j;
}
As i
is an exclusive bound, we are adding a -1
to the previous range of -1
and the increment of i
is needed. If the range [i, j)
was not empty, a 0
has been copied to position j
and we must increment j
. If the range was empty, then we had i==j
, and as we increment i
we must also increment j
to keep the invariant. We can conclude that the invariants still hold after this step.
Third case
else {
swap(A[j], A[k]);
--k;
}
A[j]
is 0
we can swap it with the value at A[k]
and decrement k
and the invariants will hold.
Termination and correctness
The final point is proving the program will terminate. Each step either:
- increment j
- decrement k
So the distance between j
and k
will decrease by 1 every step.
The distance between j
and k
is initially n-1
, and decreases by one every step. So there will be at most n-1
steps. Each step does one swap. There will be at most n-1
swaps.
At the end of the program the invariants will hold:
- from
0
to i
excluded, all -1
- from
i
to j==k
excluded, all 0
- from
j==k
to n-1
excluded, all +1