Enter the world of data structures

1. What is a data structure?

Data structures are the way computers store and organize data. (a collection of data elements that have one or more specific relationships with each other)

2. What is an algorithm?

An algorithm is a series of computational steps used to convert input data into output results. (An algorithm is a good calculation process that inputs one or a group of values ​​and produces one or a group of values ​​as output)

3. How to learn data structures and algorithms

Today's companies require students to have higher and higher coding abilities, and the questions on data structures and algorithms are becoming more and more difficult. The ability of the algorithm cannot be improved quickly in the short term, and algorithm training needs to be accumulated. During school recruitment, the written test is very difficult. In order to find a job, you need to prepare for data structures and algorithms early and train more algorithmic abilities.
Data structures and algorithms are difficult for beginners. However, as the old saying goes, nothing is difficult in the world, only those who are willing can do it. No matter how difficult data structures and algorithms are, we have to bite the bullet and learn them. I believe that as long as you learn more and practice more, learning data structures and algorithms will become easier and easier.

4. Time complexity and space complexity of the algorithm

The two dimensions of time and space can measure the quality of the algorithm .

4.1 Algorithm efficiency

After the algorithm is written into an executable program, running the program requires space resources and time resources . Therefore, measuring the quality of an algorithm is generally measured from the two dimensions of time and space , which are time complexity and space complexity .

Time complexity mainly measures how fast an algorithm runs, while space complexity mainly measures the extra space required when an algorithm runs. (In the early days of computer development, computer storage capacity was very small, and we were very concerned about space complexity. However, after the rapid development of the computer industry, computer storage capacity has reached a very high level. So we no longer need to pay special attention to it today. space complexity of the algorithm)

4.2 Asymptotic representation of Big O

Big O notation: a mathematical notation used to describe the asymptotic behavior of a function. The
derivation method of Big O's asymptotic notation:

1. Replace all additive constants in run time with constant 1.
2. In the number of runs function, only the highest order term is retained.
3. If the highest price item exists and is not 1, then remove the constant multiplied by this item, and the result will be the big O order.

There are best, average and worst cases for the time complexity of the algorithm:

Best case: maximum number of runs for any input size (upper bound)
Average case: expected number of runs for any input size
Worst case: minimum number of runs for any input size (lower bound)

For example: Search for a data x in an array of length N

Best case: found 1 time
Average case: found N/2 times
Worst case: found N times

In practice, we focus on the worst-case scenario of the algorithm . Therefore, the time complexity of searching for data in the array is O(N)

4.3 Time complexity

The definition of time complexity:
The time consumed by the execution of an algorithm cannot be calculated theoretically. Only by running the program on the machine can the time consumed be known. The time an algorithm takes is proportional to the number of executions of its statements. The number of executions of the basic operations of the algorithm is the time complexity of the algorithm.
Case 1:

Find the mathematical expression of the basic statement and problem size n, and calculate the time complexity of the algorithm.

//计算++count语句执行的次数
#include <stdio.h>
int main()
{
    
    
    int n = 0;
    scanf("%d", &n);
  
    int count = 0;

    for (int i = 0; i < n; i++)
    {
    
    
        for (int j = 0; j < n; j++)
            ++count;
    }
    for (int i = 0; i < 2 * n; i++)
    {
    
    
        ++count;
    }
    int m = 10;
    while (m--)
    {
    
    
        ++count;
    }
    printf("%d\n", count);
    return 0;
}

Number of basic operations:
F(n)=n^2+2*n+10

  • n=10 F(n)=130
  • n=100 F(n)=10210
  • n=1000 F(n)=1002010

Using Big O asymptotic representation, the time complexity is O(N^2)

  • n=10 F(n)=100
  • n=100 F(n)=10000
  • n=1000 F(n)=1000000

In practice, when we calculate the time complexity, we do not necessarily calculate the precise time complexity, but only the approximate number of executions. Here we use the asymptotic representation of Big O.

From the above, we can find that Big O's asymptotic representation removes items that have little impact on the results , and expresses the number of executions concisely and clearly.
Case 2:

计算Fun2的时间复杂度
void Fun2()
{
    
    
    int N;
    scanf("%d", &N);
    int count = 0;
    for (int i = 0; i < 2 * N; i++)
    {
    
    
        ++count;
    }
    int M = 10;
    while (M--)
    {
    
    
        ++count;
    }
    printf("%d\n", count);
}

The time complexity of Fun2 is:
F(N)=2*N+10
Asymptotic representation of big O: the time complexity is O(N)
Case 3:

//计算Fun3的时间复杂度
void Fun3()
{
    
    
    int N, M;
    scanf("%d%d", &N, &M);
    int count = 0;
    for (int i = 0; i < N; i++)
    {
    
    
        ++count;
    }
    for (int j = 0; j < M; j++)
    {
    
    
        ++count;
    }
    printf("%d\n", count);
}

The time complexity of Fun2 is:
F(N)=N+M
Asymptotic representation of big O: the time complexity is O(N)
Case 4:

//二分查找的思想
void Fun4()
{
    
    
    int m = 0;
    int arr[10] = {
    
     1,2,4,6,8,11,55,66,77,88};
    int n;
    printf("请输入要查找的数:\n");
    scanf("%d", &n);
    int begin = 0;
    int end = 9;
    while (begin <= end)
    {
    
    
        int mid = begin + (end - begin)/2;
        if (arr[mid] < n)
            begin = mid + 1;
        else if (arr[mid] > n)
            end = mid - 1;
        else
        {
    
    
            printf("找到了\n");
            printf("%d", arr[mid]);
            m = 1;
            break;
    }
    }
    if(m==0)
    printf("没找到\n");
}

Number of interval data:
N
N/2
N/2/2
…………
N/2/2/2……/2=1

In the worst case, when there is only one value left in the search interval scaling, it is bad.
Suppose you search x times, 2^x=N, so x=logN.

Asymptotic representation of Big O: time complexity is O(logN).

Case 5:

//斐波那契递归的复杂度
#include <stdio.h>
int Fun5(size_t n)
{
    
    
    if (n < 3)
        return 1;
    return Fun5(n - 2) + Fun5(n - 1);

}
int main()
{
    
    
    int n = 7;
    int sum=Fun5(n);
    printf("%d\n", sum);
    return 0;
}

Print results:
Insert image description here
Recursive expansion graph:
Insert image description here
1 time (2^ 0)
2 times (2^ 1)
4 times (2^ 2)
8 times (2^ 3)
...
2^ (N-1) times
through function recursion graph analysis The basic operation is recursive 2 ^N-1 times, and
the asymptotic representation of big O: the time complexity is O (2 ^N).

4.4 Space complexity

Definition of space complexity: A measure of the amount of storage space
an algorithm temporarily occupies during operation . (Space complexity is calculated by the number of variables) Note: The stack space required when the function is running (storing functions, local variables, some register information, etc.) has been determined during compilation. Therefore, the space complexity is mainly It is determined by the additional space requested by the function when it is run. Case 1:


//计算BubbleSort函数的空间复杂度
void BubbleSort(int* a, int n)
{
    
    
    assert(a);
    for (int end = n; end > 0; end--)
    {
    
    
        int exchange = 0;
        for (int i = 1; i < n; i++)
        {
    
    
            if (a[i - 1] > a[i])
            {
    
    
                Swap(&a[i - 1], &a[i]);
                exchange = 1;
            }
        }
        //不需要循环了
        if (exchange == 0)
            break;
    }
}

It can be seen that a constant amount of extra space is used, so the space complexity is O(1)
Case 2:

//看返回斐波那契数列的前n项,计算Fibonac的空间复杂度
int* Fibonac(int n)
{
    
    
    if (n == 0)
        return NULL;
    int* fibar = (int*)malloc(sizeof(int) * (n + 1));
    fibar[0] = 0;
    fibar[1] = 1;
    for (int i = 2; i <= n; i++)
    {
    
    
        fibar[i] = fibar[i - 1] + fibar[i - 2];
   }
    return fibar[i];
}

Dynamically opens up n+1 spaces, and the asymptotic representation of big O is O(N);

4.5 Common complexity comparison

Insert image description here

Insert image description here

Guess you like

Origin blog.csdn.net/plj521/article/details/132774947