Data structure and algorithm Chapter 1

Posted by shortj75 on Thu, 09 Sep 2021 01:34:46 +0200

preface:

  • The blogger has opened a new column "data structure and algorithm". I hope you guys can give more support. Thank you very much!

  • The blogger is currently in the initial stage of data structure. If there are any mistakes in the blog, I hope you guys will give us your advice. Thank you very much!

  • Just like everything in C, the relationship between data structure and algorithm is inseparable. When it comes to digital structure, we must talk about algorithm.

Two main indicators of algorithm efficiency: time complexity and space complexity

Time complexity (time cost of executing algorithm)

Preface:

  • Due to the influence of running environment and input rules, the absolute execution time of code is unpredictable. However, we can estimate the basic execution times T(N) of the code to estimate the code execution time. But for different algorithms, taking T(N1)=0.5N2 +0.5N, T(N2)=100N as an example, how should we compare them?

  • In order to solve the problem of time analysis, there is a gradual time complexity

Official definition:

If there is a function f(N) so that when N tends to infinity, the limit value of T(N)/f(N) is a constant that is not 0, then f(N) is a function of the same order of T(N), which is recorded as: T(N)=0(f(N)), 0 is the asymptotic time complexity of the algorithm, referred to as time complexity

Because the asymptotic time complexity is represented by capital 0, it is also called large 0 asymptotic method

  • Time complexity representation: large 0 representation

Rules:

  • If the running time is on the order of constant, it is represented by constant 1

  • Keep only the item that affects the execution times most

  • If that term exists, the coefficient in front of which term is omitted, because when N is large, the coefficient is irrelevant.

Time complexity of ordinary functions

EXP1:

/ Please calculate Func1 How many times has the basic operation been performed?
void Func1(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);
}

  • F(N)=N2 + 2*N +10
F(N)
F(10)130
F(100)10210
F(1000)1002010
...
  • When n tends to infinity, for F(N), it can be said that only N2 affects the result. Therefore, this is the reason why the big 0 is gradual

  • But for an algorithm, taking binary search as an example, we must consider different situations

Worst case scenarioThe maximum number of runs (upper bound) of any input scale, and the binary search needs to find the last
Average situationThe expected number of runs of any input scale, and the binary search needs to find the middle
Best caseThe minimum number of runs (lower bound) of any input scale can be found at the first time of binary search
  • In practice, we generally focus on the worst-case operation of the algorithm. Just like others, we should do well when the waiting time exceeds our expectations.

  • Therefore, the time complexity of fun1 is 0(N2)

EXP2:

// Calculate the time complexity of Func3?
void Func3(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: 0(M+N);

M and N are not related to each other, so the execution times are calculated independently

EXP3:

// Calculate the time complexity of BubbleSort?
void BubbleSort(int* a, int n)
{
assert(a);
for (size_t i = 0; i <n-1; i++)
{
int exchange = 0;
for (size_t j = 0; j < end-1-i; j++)
{
if (a[j] > a[j+1])
{
Swap(&a[j], &a[j+1]);
exchange = 1;
}
}
if (exchange == 0)//If there is no exchange, the array has been arranged in order from small to large
break;
}
  • Time complexity: 0(N2)

EXP4:

// Calculate the time complexity of binarysearch?
//The default array is sorted from small to large
int BinarySearch(int* a, int n, int x)
{
assert(a);
int left= 0;
int right= n-1;
while (left <= right)
{
int mid =(left+right)/2;
if (a[mid] < x)
{
    left = mid+1;
}
else if (a[mid] > x)
{
    right= mid-1;
}  
  else
  { 
      return mid;
  }
}
return -1;
}
  • Time complexity: 0(log2n)

Time complexity of recursive function

For the time complexity of recursive functions, we look at the number of recursions, that is, the depth.

EXP1:

long long Factorial(size_t N)//stratum
{
return N < 2 ? N : Factorial(N-1)*N;
}
  • Recursion depth: N, so time complexity: 0 (N)

EXP2:

long long Fibonacci(int N)
{

return N<2 ? N:Fiboncci(N-1)+Fiboncci(N-2)

}

Time complexity: 0(2^N)

Space complexity (space cost of executing algorithm):

Inter complexity is a measure of the amount of storage space temporarily occupied by an algorithm during operation. Spatial complexity is not how many bytes the program occupies, because this does not make much sense, so spatial complexity is the number of variables. The calculation rules of spatial complexity are basically similar to that of time complexity, and large O asymptotic representation is also used.

Spatial complexity of ordinary functions:

EXP1:

void BubbleSort(int* a, int n)
{
assert(a);
for (size_t i = 0; i <n-1; i++)
{
int exchange = 0;
for (size_t j = 0; j < end-1-i; j++)
{
if (a[j] > a[j+1])
{
Swap(&a[j], &a[j+1]);
exchange = 1;
}
}
if (exchange == 0)//If there is no exchange, the array has been arranged in order from small to large
break;
}

  • Space complexity: because the temporary variable (formal parameter) is a constant, space complexity: 0 (1)

EXP2:

/ calculation Fibonacci Spatial complexity?
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 ;
}

Space complexity: because N spaces are temporarily opened up, the space complexity is 0 (N)

Space complexity of recursive function:

EXP1:

// Calculate the spatial complexity of Factorial recursive Factorial?
long long Factorial(size_t N)
{
return N < 2 ? N : Factorial(N-1)*N;
}

  • Because each recursion is N times, the function stack frames N times, but each time it is a constant variable. Therefore, the space complexity is: 0 (N)

EXP2:

long long Fibonacci(int N)
{

return N<2 ? N:Fiboncci(N-1)+Fiboncci(N-2)

}
  • Recursion is a tree, so the space complexity is 0 (N)

summary

  • The blogger is currently at the entry stage of data structure, so please point out any mistakes in the blog. Thank you very much!

Topics: Algorithm data structure