什么是算法
将从以下3点进行讲解,结合课程与书籍,将自己对算法的理解做一个总结梳理,分别从1.算法的定义;2.算法时间和空间的复杂度;3.算法实例,求最大子序列和,算法相比数据结构更好理解些
1.算法的定义
1.算法是一个有限的指令集合;
2.算法接受一些输入(有些则不需要)
3.算法一定会产生输出;
4.算法一定会在有限步骤后结束;
5.算法中的每一条指令必须: a.有充分明确的目标,不可有歧义;b. 计算机可处理的范围之内 c. 描述应不依赖于任何一种计算机语言以及具体实现
2.算法时间和空间的复杂度
怎样定义一个算法的好坏,我们需要有评判的标准,而时间和空间的复杂度正是评判的标准,它们指的是给定的算法将需要多少时间和空间的资源量,如一个问题的求解算法需要长达一年时间才能完成它,这显然无用,同样,一个算法需要1GB内存也无法使用。这就要求我们尽可能优化算法,让它的时间和空间复杂度降低;
时间复杂度:根据算法写成的程序在执行过程中耗费时间的长度,T(n)表示;
空间复杂度:根据算法写成的程序在执行过程中占用存储单元的长度,S(n)表示;
复杂度的渐进表示法(T(n), S(n)均相同),以T(n)为例
1.若两段算法分别有复杂度T1(n) = O(f1(n)) 和 T2(n) = O(f2(n)), 则
T1(n)+ T2(n) = max(O(f1(n)) , O(f2(n)))
T1(n) * T2(n) = O(f1(n) * f2(n))
2.T(n)是一个关于n的k阶多项式,那么T(n) = 0(n的k次方)
3.一个for循环的时间复杂度等于循环次数乘以循环体内代码复杂度
4.if - else 结构的复杂度取决于if的条件判断复杂度和两个分支部分复杂度,总体复杂度取三者中最大
3.算法实例,求最大子序列和
算法思路——分而治之:比较大的复杂问题分成小的块,分开解决,最后再把结果合并起来
4, -3, 5, -2, -1, 2, 6, 2
该序列可分为三部分,左右两部分加上横跨这两部分通过中间的的部分;
将上述序列分为左右两部分
4, -3, 5, -2 和 -1, 2, 6, 2
再次分为
4, -3 和5, -2
-1, 2和6, 2
对子序列进行求解,然后递归
第一部分最大子序列为4
第二部分最大子序列为5
第三部分最大子序列为2
第四部分最大子序列为6
递归
第一部分最大子序列为6
第二部分最大子序列为8
递归
最大子序列为11
算法1, 时间复杂度O(N的三次方)
int MaxSubequenceSum(const int A[], int N){
int ThisSum, MaxSum, i, j, k;
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;
}
}
return MaxSum;
}
算法2, 时间复杂度O(N的二次方)
int MaxSubequenceSum(const int A[], int N){
int ThisSum, MaxSum, i, j;
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;
}
}
return MaxSum;
}
算法3, 时间复杂度O(N log N)
static int MaxSubSum(const int A[], int Left, int Right) {
int MaxLeftSum, MaxRightSum;
int MaxLeftBorderSum, MaxRightBorderSum;
int LeftBorderSum, RightBorderSum;
int Center, i;
if (Left == Right) /*当数组A中含0项或1项时,此时需分两种情况讨论,若为1,则最大子序列为A[Left]或A[Right];若为0,则返回0.*/
if (A[Left] > 0)
return A[Left];
else
return 0;
Center = (Left + Right) / 2;
MaxLeftSum = MaxSubSum(A, Left, Center);
MaxRightSum = MaxSubSum(A, Center + 1, Right);
LeftBorderSum = 0, MaxLeftBorderSum;
for (i = Center; i >= Left; i--) {
LeftBorderSum += A[i];
if (LeftBorderSum > MaxLeftBorderSum)
MaxLeftBorderSum = LeftBorderSum;
}
MaxRightBorderSum = 0, RightBorderSum = 0;
for (i = Center + 1; i <= Right; i++) {
RightBorderSum += A[i];
if (RightBorderSum <= MaxRightBorderSum)
MaxRightBorderSum = RightBorderSum;
}
return Max3(MaxLeftSum, MaxRightSum, MaxLeftBorderSum + MaxLeftBorderSum);
}
int MaxSubsequenceSum(int A[], int N) {
return MaxSubSum(A, 0, N - 1);
}
算法4,在线处理(指每输入一个数据就进行及时处理,在任何地方中止输入,算法都能给出当前的解)
时间复杂度O(N)
int MaxSubsequenceSum(const int A[], int N) {
int ThisSum, MaxSum, i;
ThisSum = MaxSum = 0;
for (i = 0; i < N; i++) {
ThisSum += A[i];
if (ThisSum > MaxSum)
MaxSum = ThisSum;
else if (ThisSum)
ThisSum = 0;
}
return MaxSum;
}