Data Structure and Algorithm Analysis Study Notes (2)-algorithm analysis, data structure and algorithm analysis
I. Simplest understanding and use of algorithm analysis methods
1. First, you may be confused by the mathematical concepts. In fact, simply put, it is assumed that the execution efficiency of any statement is the same, therefore, the execution time of each statement is set to a time unit, so as long as the number of statements executed by this program is calculated, the time complexity can be calculated.
2. Second, we need to understand that we are an estimate, so we can simplify it. Obviously, we can ignore the relatively low-level items and only wash the highest-level items. Then there are common rules:
(1) FOR Loop
The running time of a for loop is at most the running time of the statements in the for loop multiplied by the number of iterations.
(2) nested FOR Loop
It must be the number of executions of the innermost loop statement, and then multiplied by the number of iterations of the loop.
(3) entire program
In fact, we can find the largest number of loop iterations, and the most nested computing is good.
3. Of course, we only calculate the approximate value. In order to simplify the calculation, we can perform proper amplification to calculate the time complexity only by considering the worst and worst cases.
Ii. Maximum subsequence
There are four different solutions in the book to further strengthen how we calculate the time complexity. I also learned how to take notes here.
Question: calculate the maximum subsequence value in an integer sequence.
Algorithm 1:
Int MaxSubsequenceSum1 (const int A [], int N)
{
Int thisSum, MaxSum;
MaxSum = 0;
For (int I = 0; I <N; I ++)
{
For (int j = I; j <N; j ++)
{
ThisSum = 0;
For (int K = I; K <= j; K ++)
{
ThisSum + = A [K];
}
If (thisSum> MaxSum)
{
MaxSum = thisSum;
}
}
}
If (MaxSum = 0)
{
Int I;
For (I = 0; I <N; I ++)
{
If (A [I]! = 0)
Break;
}
If (I! = N)
{
Int Max = A [0];
For (int j = 0; j <N; j ++)
{
If (A [j]> Max)
{
Max = A [j];
}
}
MaxSum = Max;
}
}
Return MaxSum;
}
We can see that the maximum for loop has three elements, and the worst possible iterations are all N, so we can easily conclude that, the time complexity of this algorithm is O (N ^ 3). The most obvious waste of resources is the repeated calculation of the subsequence value from low I to the k, therefore, the algorithm is simply modified.
Algorithm 2:
Int MaxSubsequenceSum2 (const int A [], int N)
{
Int thisSum, MaxSum;
MaxSum = 0;
For (int I = 0; I <N; I ++)
{
ThisSum = 0;
For (int j = I; j <N; j ++)
{
ThisSum + = A [j];
If (thisSum> MaxSum)
{
MaxSum = thisSum;
}
}
}
If (MaxSum = 0)
{
Int I;
For (I = 0; I <N; I ++)
{
If (A [I]! = 0)
Break;
}
If (I! = N)
{
Int Max = A [0];
For (int j = 0; j <N; j ++)
{
If (A [j]> Max)
{
Max = A [j];
}
}
MaxSum = Max;
}
}
Return MaxSum;
}
In fact, even if the accumulative strategy is adopted, the efficiency is greatly improved. Therefore, this is also a small technique to improve algorithm efficiency, that is, we try our best to reduce unnecessary computing, use existing computing results whenever possible.
Algorithm 3:
Int Max3 (const int a, const int B, const int c)
{
Int temp = (a> B )? A: B;
Temp = (temp> c )? Temp: c;
Return temp;
}
Int MaxSubSum (const int A [], int Left, int Right)
{
Int MaxLeftSum, MaxRightSum;
Int MaxLeftBorderSum, MaxRightBorderSum;
Int LeftBorderSum, RightBorderSum;
If (Left = Right)
{
If (A [Left]> 0)
Return A [Left];
Else
Return 0;
}
Int center = (Right + Left)/2;
MaxLeftSum = MaxSubSum (A, Left, center );
MaxRightSum = MaxSubSum (A, center + 1, Right );
LeftBorderSum = MaxLeftBorderSum = 0;
For (int I = center; I> = Left; I --)
{
LeftBorderSum + = A [I];
If (LeftBorderSum> MaxLeftBorderSum)
{
MaxLeftBorderSum = LeftBorderSum;
}
}
RightBorderSum = MaxRightBorderSum = 0;
For (int I = center + 1; I <= Right; I ++)
{
RightBorderSum + = A [I];
If (RightBorderSum> MaxRightBorderSum)
{
MaxRightBorderSum = RightBorderSum;
}
}
Return Max3 (MaxLeftSum, MaxRightSum, MaxLeftBorderSum + MaxRightBorderSum );
}
Int MaxSubsequenceSum3 (const int A [], int N)
{
Int MaxSum = MaxSubSum (A, 0, N-1 );
If (MaxSum = 0)
{
Int I;
For (I = 0; I <N; I ++)
{
If (A [I]! = 0)
Break;
}
If (I! = N)
{
Int Max = A [0];
For (int j = 0; j <N; j ++)
{
If (A [j]> Max)
{
Max = A [j];
}
}
MaxSum = Max;
}
}
Return MaxSum;
}
This algorithm uses the idea of divide and conquer, as well as recursive thinking, that is, to continuously break down a problem into subproblems of similar sizes and sizes to solve it, so here we need the largest subsequence of a sequence, in fact, to find the largest subsequence of the left half, with a companion part and the middle part, and to find the left half, the largest subsequence in the second half is obviously smaller, so it can be used recursively until there is a number left. in the middle part, take the largest subsequence from right to left on both sides and from left to right on the left. Then sum up as the value of the intermediate part, and compare the value of the intermediate part, the left half, and the second half to get the result.
Algorithm 4:
Int MaxSubsequenceSum4 (const int A [], int N)
{
Int thisSum, MaxSum;
ThisSum = MaxSum = 0;
For (int I = 0; I <N; I ++)
{
ThisSum + = A [I];
If (thisSum> MaxSum)
{
MaxSum = thisSum;
}
Else if (thisSum <0)
{
ThisSum = 0;
}
}
If (MaxSum = 0)
{
Int I;
For (I = 0; I <N; I ++)
{
If (A [I]! = 0)
Break;
}
If (I! = N)
{
Int Max = A [0];
For (int j = 0; j <N; j ++)
{
If (A [j]> Max)
{
Max = A [j];
}
}
MaxSum = Max;
}
}
Return MaxSum;
}
The last algorithm is awesome. It's just N-order. You can think about how fast the algorithm is, and if it's all negative, you can also read the data at any time and release the powerful memory functions at any time.
Which language is better to describe how to learn Data Structure and algorithm analysis? C/C ++?
If you are not very familiar with C ++, the C language description is more intuitive when learning algorithms. Furthermore, there is an authoritative introduction to algorithms in algorithm learning. This book is very deep, so it is very interesting to read it carefully. In addition, the language itself is the carrier for implementing algorithms, so it is also necessary to learn a language.
Question about the code implementation of "usable space table" in "data structure and algorithm analysis" (C ++ version 2)
It's not what the landlord said.
It means that you can initialize a piece of memory and store it in
Link <Elem> * Link <Elem>: freelist
When we need to apply for memory, we only need to quickly retrieve a segment from freelist.
However, after freelist is used, call the default: new in C ++ to apply.
Memory;
However, the initialization part of freelist in this code is not provided.