什么是算法

什么是算法

将从以下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;
}

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值