How to calculate this radix sorting algorithm complexity? - algorithm

I have this following code. I need to calculate this algorithm complexity but i have no idea where to start. This algorithm has 3 nested loops so i guess its complexity is n^3 or am i wrong?
public static void RadixSort(DataArray data)
{
IList> digits = new List>();
for (int i = 0; i < 10; i++)
{
digits.Add(new List<int>());
}
for (int i = 0; i < data.Length; i++)
{
for (int j = 0; j < data.Length; j++)
{
int digit = (int)((data[j] % Math.Pow(10, i + 1)) / Math.Pow(10, i));
digits[digit].Add((int)data[j]);
}
int index = 0;
for (int k = 0; k < digits.Count; k++)
{
IList<int> selDigit = digits[k];
for (int l = 0; l < selDigit.Count; l++)
{
data.Swap(index++, selDigit[l]);
//data[index++] = selDigit[l];
}
}
for (int k = 0; k < digits.Count; k++)
{
digits[k].Clear();
}
}
}

Calculating complexity is more complex than just look at the number of nested loops. If you have a triple nested loop like this:
for(int i=0; i<n; i++)
for(int j=0; j<n; j++)
for(int k=0; k<n; k++)
it will be O(n³), assuming n is not changing in the loop. However, if you consider your case:
for(int i=0; i<n; i++)
for(int j=0; j<m; j++)
for(int k=0; k<m; k++)
the time complexity will instead be O(m²n).
And even the simplest sorting algorithms, like bouble sort, selection sort and insertions sort is O(n²), so if your implementation is worse than that you're doing something wrong. The time complexity for radix sort is O(wn), where w is a measure of the size of the elements.

When uncertain about complexity, a reasonable approach is to add counters to the inner-loop code and at the end of the routine print out the counts. Next, vary the size of the input to see how the results change. The empirical results can immediately confirm or deny your analytic or intuited results.

Related

Running Time of Nested Loops, When inner loop false,

01.) Considering the growth time, When the inner loop of a nested loop is false, is its growth time O (n)?
ex:
for (int i=0; i<n; i++){
for (int j=0; j>n; i++){
//some code
}
}
02.) Considering the growth time, When the inner loop of a nested loop has another array length variable as 'm', is its growth time O (n m)?
ex:
for (int i=0; i<n; i++){
for (int j=0; j<m; i++){
//some code
}
}
What is the running time of the following code? (please explain with steps)
for (int i = 0; i < n; i++) {
for (int j = 0; j > n; j++) {
for (int k = 0; k > n; k++) {
System.out.println("*");
}
}
}
Thank You.
Yes, if it is absolutely clear that inner loop will not be executed due to the conditional's being false regardless of the input size, then time complexity will be O(n).
Yes, a detailed analysis can be found below. However, I assume you incorrectly incremented i in your inner loop.
for (int i=0; i<n; i++){
for (int j=0; j<m; j++){ // j++
//some code
}
}
number of operations performed by inner loop in each iteration of outer loop : m
number of operations performed by outer loop : n
Total number of operations : n*m
Time complexity f(n) ∈ O(n*m)
If the code you posted is not incorrect, then the time complexity analyis:
for (int i=0; i<n; i++){
for (int j=0; j<m; i++){
//some code
}
}
j=0 --> j<m (i++)
If 0<m, then it is an infinite loop. It's pointless to make a time complexity analysis.
If 0>=m, then inner loop is not going to be executed, therefore time complexity will be O(n).
Detailed analysis:
for (int i = 0; i < n; i++) { // n many times
for (int j = 0; j > n; j++) { // n many times
for (int k = 0; k > n; k++) { // n many times
System.out.println("*");
}
}
}
All of the loops are iterated n many times. Most-inner loop will perform n operations. Outer loop will perform n, which makes n*n. And most-outer loop will perform n operations, which makes n*n*n in total.
Time complexity f(n) ∈ O(n^3)

Calculate the big-O and big-Omega of the following piece of code

I was asked to find the big-O and Big-Omega if I know that function f has O(log(n)), Ω(1) and function g has O(n), Ω((log(n))^2)
for (int i = n; i >= 0; i/=2)
if (f(i) <= g(i))
for (int j = f(i)*f(i); j < n; j++)
f(j);
The big problem that I have is that I don't know how to incorporate the complexity of the funstions in the calculation. I mean I know how to calculate the complexity of loops that looks like this:
for(int i =0 ; i< n*2; i++) {
....
}
or like this
for(int i = 0; i < n; i++) {
for(int j = 0; j < n; j++) {
}
}
Thank you in advance.
This is what I've tried:
for (int i = n; i >= 0; i/=2)// this is aproximatly O(log(n))
if (f(i) <= g(i))// because O(n) < O(log(n)) this line is O(n)
for (int j = f(i)*f(i); j < n; j++)// O(n*log(n))
f(j);// O(log(n))
So by my calculation I get O(log(n)*n *n *log(n)*log(n))=O(n^2*log^3(n))
This is tricky question, because the loop execution depends on values, returned by functions f and g. However remember, that you need to estimate the worst case - so you need to assume two things:
f(i) <= g(i) is always true, so the internal loop always executes
the internal loop starts from 0, because it's a minimal value, which you can get as a result of squaring the f(i) value
So, your piece of code becomes much simpler:
for (int i = n; i >= 0; i/=2)
{
f(i);
g(i);
f(i);
f(i);
for (int j = 0; j < n; j++)
f(j);
}
I think you can take over from here.

How to determine the precise (i.e., not just the order of magnitude) Big-Oh values based on the number of statement executions?

I am studying Data Structures, but I am a bit confused about my homework assignment. I am trying to figure out how to count the precise Big-Oh values of the following:
for (int i = 0; i < n; i++)
{
for (int j = i; j < n; j++)
{
for (int k = j; k < n; k++)
{
sum += j;
}
}
}
I know how to count the Big-Oh's in terms of magnitude, but I don't know how to count it precisely. An example answer is in the form: 10N + 3n^2 + 2 (IE)

Algorithmic big o order of growth code

I'm doing an online course and i'm stuck on this question. I know there are similar questions but they don't help me.
What is the order of growth of the worst case running time of the
following code fragment as a function of N?
int sum = 0;
for (int i = 0; i*i*i < N; i++)
for (int j = 0; j*j*j < N; j++)
for (int k = 0; k*k*k < N; k++)
sum++;
I thought that the order would be n^3 but I don't think this is correct because the loops only go through a third of n each time. So would that make it nlogn?
Also
int sum = 0;
for (int i = 1; i <= N; i++)
for (int j = 1; j <= N; j++)
for (int k = 1; k <= N; k = k*2)
for (int h = 1; h <= k; h++)
sum++;
I think this one would be n^4 because you have n * n * 0.5n * 0.5n
The loops in fact only go up to the cube root of N. (i^3 < n, etc.)
The 3 nested loops of this length, give O(cube root of N, cubed). This O(N)
Of note, if you were correct and they each went to one third of N, then cubing this still gives O(N^3/9), 1/9 is constant, so this is O(n^3)
If you examine the value of sum for various values of N, then it becomes pretty clear what the time complexity of the algorithm is:
#include <iostream>
int main()
{
for( int N=1 ; N<=100 ; ++N ) {
int sum = 0;
for (int i = 0; i*i*i < N; i++)
for (int j = 0; j*j*j < N; j++)
for (int k = 0; k*k*k < N; k++)
sum++;
std::cout << "For N=" << N << ", sum=" << sum << '\n';
}
return 0;
}
You can then draw your own conclusions with greater insight.

Order of growth of as function of N

I'm practicing with algorithm complexities, I thought all the codes below were quadratic in terms of the order of growth but since I need the order of growth as a function of N, I think that changes things and I don't know exactly how to work it out.
int sum = 0;
for(int n = N; n > 0; n/=2)
for(int i = 0; i < n; i++)
sum++
int sum = 0;
for(int i = 1; i < N; i*=2)
for(int j = 0; j < i; j++)
sum++
int sum = 0;
for(int i = 1; i < N; i*=2)
for(int j = 0; j < N; j++)
sum++
int sum = 0;
for(int n = N; n > 0; n/=2)
for(int i = 0; i < n; i++)
sum++
This is O(N), the inner loop runs total of N + N/2 + N/4 + ... + 1 times, this sum converges to 2N when N->infinity, and thus it is O(N).
int sum = 0;
for(int i = 1; i < N; i*=2)
for(int j = 0; j < i; j++)
sum++
This is very similar to case1, and I am going to leave it to you as practice. Follow the same approach I did there, and you will get the answer.
int sum = 0;
for(int i = 1; i < N; i*=2)
for(int j = 0; j < N; j++)
sum++
Here, the main difference is the inner loop does not depend on the variable of the outer loop. This means, regardless of value of i, inner loop is going to repeat N times.
So, you need to realize how many times the outer loop will repeat, and multiply it with N.
I leave it as well for you as practice after explaining these guidelines.

Resources