Uncoiling data structure? You have to grasp the complexity of time and space!! If you can't, let uncle come~

catalogue

preface

Algorithm efficiency

Time complexity

Asymptotic representation of large O

Common time complexity calculation examples

Spatial complexity

Examples of common space complexity calculation

preface

This chapter mainly explains:

  1. Explanation of time complexity and space complexity
  2. Common complexity related exercises

Algorithm efficiency

The algorithm needs time-consuming resources and space (memory) resources when running
  • Criteria for measuring the quality of an algorithm:
It is generally measured from the two dimensions of time and space
Time complexity mainly measures the running speed of an algorithm
The spatial complexity mainly measures the additional space required for the operation of an algorithm
Note: at present, we do not pay special attention to the spatial complexity of an algorithm (scientific and Technological Development / Moore's law)

Time complexity

  •   Concept:
The time complexity of the algorithm is a function, which quantitatively describes the running time of the algorithm
This is not the actual time consumed by the algorithm, but the execution times of the basic operations in the algorithm
Finding the mathematical expression between a basic statement and the problem scale N is to calculate the time complexity of the algorithm
Note: the actual calculation time complexity does not necessarily need to calculate the exact execution times, but only the approximate execution times (progressive representation of large O)

Asymptotic representation of large O

Big O notation is a mathematical symbol used to describe the asymptotic behavior of a function
  • Derivation of large O-order method:
  1. Replace all addition constants in the run time with 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 this item, and the result is large O-order
  • In short:
The progressive representation of big O removes those items that have little impact on the results, and succinctly and clearly shows the number of executions  
  • Example:
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);
}

Number of basic operations performed:

Progressive representation of large O:
  • be careful:
In practice, the time complexity of some algorithms has the best, average and worst cases. In general, we focus on the worst case of the algorithm
  • Example: search for a data x in an array of length N
Best case: 1 time
Worst case: found N times
Average: N/2 times
The time complexity of searching data in this array is: O(N)

Common time complexity calculation examples

  • Example 1:
void Func1(int N) {
 int count = 0;
 for (int k = 0; k < 2 * N ; ++ k)
 {
 ++count;
 }
 int M = 10;
 while (M--)
 {
 ++count;
 }
 printf("%d\n", count);
}
Time complexity: O(N)
  • Example 2:
void Func2(int N, int M) {
 int count = 0;
 for (int k = 0; k < M; ++ k)
 {
 ++count;
 }
 for (int k = 0; k < N ; ++ k)
 {
 ++count;
 }
 printf("%d\n", count);
}

Time complexity: O(N+M)

  • Example 3:
void Func3(int N) {
 int count = 0;
 for (int k = 0; k < 100; ++ k)
 {
 ++count;
 }
 printf("%d\n", count);
}

Time complexity: O(1)

Note: it is not executed once, but represents constant times

  • Example 4:
// The time complexity of calculating strchr?
//Find a character in the string and return the corresponding address (similar to the traversal algorithm)
const char * strchr ( const char * str, int character );

Time complexity: O(N)

  • Example 5:
// Calculate the time complexity of BubbleSort?
void BubbleSort(int* a, int n) {
 assert(a);
 for (size_t end = n; end > 0; --end)
 {
 int exchange = 0;
 for (size_t i = 1; i < end; ++i)
 {
 if (a[i-1] > a[i])
 {
 Swap(&a[i-1], &a[i]);
 exchange = 1;
 }
 }
 if (exchange == 0)
 break;
 }
}

Execution times expression: n-1+n-2+n-3+...+1=n (n-1) / 2 (sum of equal differences)

Time complexity: O(N^2)

  • Example 6:
// Calculate the time complexity of BinarySearch?
int BinarySearch(int* a, int n, int x) 
{
 assert(a);
 int begin = 0;
 int end = n-1;
 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; 
}

Execution times expression:

Note: x is the search times in the worst case, and N is the array length

Reverse thinking: push back from finding. The number of each push back is x2. After x times, the final total number is the total length of the array

The time complexity is:

  • Example 7:
// The time complexity of computing factorial recursive Fac?
long long Fac(size_t N) 
{
 if(0 == N)
 return 1;
 
 return Fac(N-1)*N; 
}

Number of executions expression: n

Time complexity: O(N)

  • Example 8:
// The time complexity of computing Fibonacci recursive Fib?
long long Fib(size_t N) 
{
 if(N < 3)
 return 1;
 
 return Fib(N-1) + Fib(N-2);
}

Note: in fact, the call on the right will end faster than that on the left, that is, some items will be missing on the right

Execution times expression:(equal ratio summation, C is constant)

The time complexity is:

Spatial complexity

  • Concept:
Space complexity is also a mathematical expression, which is a measure of the temporary storage space occupied by an algorithm during operation
Space complexity is not how many bytes the program occupies, but the number of variables
The calculation rules of spatial complexity are basically similar to the practical complexity, and the large O asymptotic representation is also used
Note: the stack space (storage parameters, local variables, some register information, etc.) required by the function during operation has been determined during compilation, so the space complexity is mainly determined by the additional space explicitly applied by the function during operation

Examples of common space complexity calculation

  • Example 1:
// Calculate the spatial complexity of BubbleSort?
void BubbleSort(int* a, int n) 
{
 assert(a);
 for (size_t end = n; end > 0; --end)
{
 int exchange = 0;
 for (size_t i = 1; i < end; ++i)
 {
 if (a[i-1] > a[i])
 {
 Swap(&a[i-1], &a[i]);
 exchange = 1;
 }
 }
 if (exchange == 0)
 break;
 }
}
Note: two additional spaces are used
Space complexity is  : O(1)
  • Example 2:
// Calculate the spatial complexity of Fibonacci?
// Returns the first n items of the Fibonacci sequence
long long* Fibonacci(size_t n) 
{
 if(n==0)
 return NULL;
 
 long long * fibArray = (long long *)malloc((n+1) * sizeof(long long));
 fibArray[0] = 0;
 fibArray[1] = 1;
 for (int i = 2; i <= n ; ++i)
 {
 fibArray[i] = fibArray[i - 1] + fibArray [i - 2];
 }
 return fibArray; 
}

Note: the space complexity depends on the additional space consumption. When the Fibonacci sequence branch calls to the end, it starts to return, and the return will destroy the function stack frame, so at most N function stack frames (space) can be opened up

Space complexity: O(N)
  • Example 3:
// Calculate the spatial complexity of factorial recursive Fac?
long long Fac(size_t N) 
{
 if(N == 0)
 return 1;
 
 return Fac(N-1)*N; 
}

  Note: N recursive calls are made, and N additional function stack frames (space) are opened up

Space complexity: O(N)

Tags: data structure

Posted on Mon, 18 Oct 2021 15:25:32 -0400 by Nightslyr