数据结构时间复杂度计算
2015-10-25 19:30
302 查看
(1)FOR循环
一次for循环的运行时间至多是该for循环内语句的运行时间乘以迭代次数。
(2)嵌套的FOR循环
肯定是计算最内层循环语句的执行次数,然后再乘以所以循环的迭代次数。
(3)整个程序
其实找到循环迭代次数最多,嵌套最多的进行计算就好。
3、当然,我们计算的只是大概值,而且为了计算的简便,我们一边进行适当的放大,即只考虑最坏最坏的情况,算出其时间复杂度即可。
二、最大子序列
书中通过4种不同的解法来进一步强化我们应该如何计算时间复杂度,小白我也好好学习了下,在此写下学习笔记。
题目:算出一个整数序列中最大的子序列的值。
算法一:
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;
}
我们可以看出其最大的for循环有三重,而且最坏的可能迭代次数都是N,所以我们可以很容易的得出,此算法的时间复杂度为O(N^3),其中资源最明显的浪费就在重复计算了从低i到第k的子序列的值,所以算法二便是进行了简单的修改。
算法二:
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;
}
其实改变的地方即使采用的累加的策略而已,但却使效率大大的提高了,所以这里也是提高算法效率的一个小小的技巧,即尽力减少不必要的计算,尽量利用现有的计算结果。
算法三:
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;
}
这个算法使用了分治的思想,还有递归的思想,即把一个问题不断的分解成类似的规模更小的子问题来解决,所以这里我们要求一个序列的最大子序列,其实就是求左半部分,有伴部分和中间部分的最大子序列,而求左半部分,后半部分的最大子序列显然是将问题的规模变小了,所以可以递归使用,直到剩下一个数的情况.而中间部分呢,则取左右两边,左边从右往左,右边从左往右的最大子序列。然后加起来作为中间部分的值,最后比较中间部分,左半部分,后半部分三部分的值就可以得到结果啦。
算法四:
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;
}
一次for循环的运行时间至多是该for循环内语句的运行时间乘以迭代次数。
(2)嵌套的FOR循环
肯定是计算最内层循环语句的执行次数,然后再乘以所以循环的迭代次数。
(3)整个程序
其实找到循环迭代次数最多,嵌套最多的进行计算就好。
3、当然,我们计算的只是大概值,而且为了计算的简便,我们一边进行适当的放大,即只考虑最坏最坏的情况,算出其时间复杂度即可。
二、最大子序列
书中通过4种不同的解法来进一步强化我们应该如何计算时间复杂度,小白我也好好学习了下,在此写下学习笔记。
题目:算出一个整数序列中最大的子序列的值。
算法一:
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;
}
我们可以看出其最大的for循环有三重,而且最坏的可能迭代次数都是N,所以我们可以很容易的得出,此算法的时间复杂度为O(N^3),其中资源最明显的浪费就在重复计算了从低i到第k的子序列的值,所以算法二便是进行了简单的修改。
算法二:
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;
}
其实改变的地方即使采用的累加的策略而已,但却使效率大大的提高了,所以这里也是提高算法效率的一个小小的技巧,即尽力减少不必要的计算,尽量利用现有的计算结果。
算法三:
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;
}
这个算法使用了分治的思想,还有递归的思想,即把一个问题不断的分解成类似的规模更小的子问题来解决,所以这里我们要求一个序列的最大子序列,其实就是求左半部分,有伴部分和中间部分的最大子序列,而求左半部分,后半部分的最大子序列显然是将问题的规模变小了,所以可以递归使用,直到剩下一个数的情况.而中间部分呢,则取左右两边,左边从右往左,右边从左往右的最大子序列。然后加起来作为中间部分的值,最后比较中间部分,左半部分,后半部分三部分的值就可以得到结果啦。
算法四:
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;
}
相关文章推荐
- 学习笔记之数据结构与算法(三)
- 队列的链式表示和实现
- 排序算法之快速排序
- 数据结构之必需知
- 数据结构学习系列之线性表(五)
- 数据结构实践项目——树和二叉树
- MySQL索引背后的数据结构及算法原理
- 数据结构实践项目——树和二叉树(1)
- 常见排序算法小结
- 判断图的连通分量
- 图的连通性判断
- Java 笔试:数据结构笔记
- STL中提供-二分查找算法
- 学习笔记之数据结构与算法(二)
- 内存管理器(七)Glibc malloc 实现(三)--多线程思想(先占个坑)
- JavaScript描述数据结构与算法——列表
- R语言的数据类型和数据结构
- 引用 Map 数据结构的排序问题
- Java 的 ArrayList 的底层数据结构
- JSON数据结构学习