loop invariant of bidirectional bubble sort - loops

for(i=1; i<= ⌈(N+1)/2⌉; i++) do
for(j=i; j<=N-i; j++) do
if(A[j]>A[j+1]) then
swap(A[j],A[j+1]);
for(k=N-i; k>i; k--) do
if(A[k]<A[k-1]) then
swap(A[k],A[k-1]);
This the pseudo code for bidirectional bubble sort. I need to find loop invariant for the second loop(first inner loop). What I was thinking that loop invariant for this loop is all the elements before current j are smaller than it
A[h]<A[j] for all h between i and j
However, solution manual says something else. Any help is appreciated!

Related

Which is the order of filling a triangular matrix?

I'm filling a lower triangular matrix like this:
for (i = 0; i < size; i++) {
for (j = 0; j <= i; j++)
l[i][j] = j + 1;
}
And I want to calculate the order of the code in Big O notation but I'm really bad. If it was a regular matrix it would be O(n²) but in this case I'm not sure if it's O(nlog(n)) or something like that.
Typically (but not always) one loop nested in another will cause O(N²).
Think about it, the inner loop is executed i times, for each value of j. The outer loop is executed size times.
This comes out to be 1/2 of N^2, which is still O(N^2)

How to calculate the complexity of this function?

I'm wondering what is the time-complexity of the inner for-loop, is it sqrt(n) or log(n)?
void foo(int n)
{
for (int i=0; i<n*n; ++i)
for (int j=1; j*j<n; j*=2)
printf("Hello there!\n");
}
j in inner for loop will take values 1,2,4,...2^t
Also according to constraint given,
2^2t = n
So, t = (1/2)logn
Therefore the inner loop should have Time Complexity O(log(n))
I think the inner for-loop has complexity O(sqrt(n)). To make it O(log(n)), the inner for loop should be something like this:
EDIT
It should be O(log(n)).

Calculating the complexity of this function

This is the function:
void f(int n)
{
for(int i=0; i<n; ++i)
for(int j=0; j<i; ++j)
for(int k=i*j; k>0; k/=2)
printf("~");
}
In my opinion, the calculation of the time complexity would end up to be something like this:
log((n-1)(n-2))+log((n-1)(n-3))+...+log(n-1)+log((n-2)(n-3))+...+log(n-2)+...log(2)
So, I get a time complexity of nlog(n!) (because loga+logb=log(a*b) and because n-1,n-2,n-3,... each appears n-1 times in total.
However, the correct answer is n^2*logn, and I have no idea where my mistake is. Could anyone here help?
Thanks a lot!
log(n!) can be approximated as (n+1/2)log(n) - n + constant (see https://math.stackexchange.com/questions/138194/approximating-log-of-factorial)
So the complexity is n*n*log(n) as expected.
Simpler: compute the complexity loop by loop independently and multiply them.
First 2 outer loops: trivial: n each, which makes n^2
Inner loop: has a log(n**2) complexity which is the same as log(n)
So n^2log(n) is the correct answer.
The Complexity is O(N*N*LOG_2(N^2)).
The first and the second loop both have O(N) and the last loop in k has logarithmic grow.
LOG_2(N^2) = 2*LOG_2(N) and
O(N*M)=O(N)*O(M).
O(constant)=1.
So for the grow of the last loop you can write also O(LOG_2(N^2))=O(LOG(N)).

Avoiding double for loop

I was wondering if there was a better way to do this.
I have a nested loop in an nbody gravity sim where by each ball in a list of balls checks all balls to get the distance/mass and apply gravitational force to the ball's vectors.
something like this:
for(int i = 0; i < balls.size(); i++){
for(int j = 0; j < balls.size(); j++){
balls.get(i).applyForce(balls.get(j));
}
}
Is there a different data structure I could use that could help me avoid the double loop?
I know this is a very general question, I'm just after a hint in the right direction.
Given you're testing a list of elements, and it's relationship to every other element - you're talking an O(N^2) algorithm. So no, not really.
The best you might accomplish is to discard previously tested relationships (if relevant). If you're testing 'i' vs. 'j' then you don't need to re-iterate from zero necessarily.
You could therefore probably start the second loop at i+1 unless you really need to test i -> j and also j -> i.

Algorithm Complexity loop

Time complexity of a triple-nested loop
for(int i=0; i<n; i++)
for(int j=i+1; j<n; j++)
for(int k=j+1; k<n; k++)
I want to know the right solution of time complexity.
A formal solution to determine the order of growth of your algorithm:
First guess: three loops depending on n, so it should be O(n³)
If you try to compute the exact complexity you have to compute it for the inner an multiply it with the outer loop.
inner loop takes O(n-k)
middle loop takes O(n-j + n-j-1 + ... + n-j-n) = O((n-j) ⋅ (n-j+1) / 2) = O((n-j)²)
outer loop takes O((n-1)² + (n-2)² + ... + (n-n+1)²) = O(n³)
Sure this is not exact, but in terms of big-O it is exact enought.

Resources