1. Concept
Time complexity is a function that quantitatively describes the running time of the algorithm.
The number of executions of the basic operations in the algorithm is the time complexity of the algorithm.
Example:
//语句中count++;被执行多少次?
void func(int N)
{
int count = 0;
for(int i = 0; i < N; i++)
{
for (int j = 0; j < N; j++)
{
count++;
}
}
for (int k = 0; k < 2 * N; k++)
{
count++;
}
int M = 10;
while (M--)
{
count++;
}
printf("%d\n", count);
}
Time complex function: f(N) = N^2 + 2*N + 10
When N->infinity, the effect of the last two items on the overall result is negligible.
For the convenience of expression, the big-O asymptotic notation is used.
Hit O notation: Mathematical notation used to describe the asymptotic behavior of a function.
Derivation of Big-O-Order Methods
1) Replace all addition functions in runtime with the constant 1 .
2) In the modified run times function, only the highest-order term is retained .
3) If the highest-order term exists and is not 1 , remove the constant multiplied by the number of terms , and the result is the big-O order.
The general focus is on the worst-case operation .
Example:
//计算count++被运行了多少次?
void fun()
{
int count = 0;
for (int i = 0; i < 100; i++)
{
count++;
}
printf("%d\n", count);
}
After 100 cycles, it is O(1) according to the big O order rule.
//语句中count++;被执行多少次?
void func(int N)
{
int count = 0;
for(int i = 0; i < N; i++)
{
for (int j = 0; j < N; j++)
{
count++;
}
}
for (int k = 0; k < 2 * N; k++)
{
count++;
}
int M = 10;
while (M--)
{
count++;
}
printf("%d\n", count);
}
The time complexity function is f(N) = N+2*N+10, which is expressed as: O(N^2) according to the big O order
//计算时间复杂度
void fun(int N, int M)
{
int count = 0;
for (int i = 0; i < M; i++)
{
count++;
}
for (int i = 0; i < N; i++)
{
count++;
}
printf("%d\n", count);
}
If N and M are unknown, it can be expressed as O(N+M)
For the bubble function we know
void Bubble_sort(int* a, int n)
{
for (int end = n; end > 0; end--)
{
int exchange = 0;
for (int i = 1; i < end; i++)
{
if (a[i - 1] > a[i])
{
swap(&a[i], &a[i - 1]);
exchange = 1;
}
}
if (exchange == 0)
break;
}
}
Worst case f(N) = (N-1)*N/2
Best case: f(N) = N
So the time complexity of bubbling is O(N^2)
Dichotomous time complexity
int BinarySearch(int* a, int n, int x)
{
int begin = 0;
int end = n;
while (begin < end)
{
int mid = begin + ((end - begin) >> 1);
if (a[mid] < x)
begin = mid + 1;
else if (a[mid] > x)
{
end = mid;
}
else
return mid;
}
return -1;
}
Best case: O(1)
Worst case: O(logN)
f(N) = N/2/2..../2 = 1; --> 2^x = N -->x = logN
Note: The time complexity will be written as logN
Advanced:
Recursive Algorithm Time Complexity Calculation
1) Each function call is O(1) , then it depends on the number of recursion .
2) Each function call is not O(1) , then it depends on the accumulation of the number of recursive calls.
Example:
int fun(int N)
{
if (N == 0)
return 1;
return N * fun(N - 1);
}
The time complexity is O(N)
The first time: N*fun(N-1)
Second time: (N-1)*fun(N-2)
……
N-1th 1*fun(0)
Nth time: 1
This is the first case, just look at the number of recursion.
int fun(int N)
{
if (N == 0)
{
return 1;
}
for (int i = 0; i < N; i++)
{
printf("%d\n", i);
}
printf("\n");
return fun(N - 1) * N;
}
The first recursion: execute the loop N times
Second recursion: execute the loop N-1 times
……
N-1th time: execute the loop 2 times
Nth time: Execute the loop 1 time
Summation shows that f(N) = N+N-1+N-2+…+1 = N*(N+1)/2 ~ N^2
This is the second case
Calculate the time complexity of the recursive writing of the Fibonacci sequence
int fun(int N)
{
if (N < 3)
return 1;
return fun(N - 1) + fun(N - 2);
}
The time complexity is O(2^N)
calculation process:
Start statement: fun(N)
The first time: fun(N-1) + fun(N-2)
Second: fun (N-2) + fun (N-3) + fun (N-3) + fun (N-4)
……
It is known that:
Each call is made twice, recursively looping N times
f(N) = 1+2+4+……+2^(N-2) ~ 2^N
Xiaobai, please correct me if I make a mistake.