(笔记)数据结构第一讲-基本概念
来源:互联网 发布:脸部黄金比例测试软件 编辑:程序博客网 时间:2024/04/28 18:49
第一讲 基本概念
空间复杂度S(n)
根据算法写成的程序在执行时占用储存单元的长度。
时间复杂度T(n)
根据算法写成的程序在执行时耗费时间的长度。
例题1
void Print(int N){ if(N){ Print(N-1); printf("%d\n",N); } return;}
物理存储:每递归一次需要申请一个方法临时变量的储存内存
PrintN(100000) PrintN(99999) PrintN(99998) PrintN(99997) ...... PrintN(0)
空间复杂度
S(n)=N
二分法
int BinarySearch1(int a[],int n,int x){ int left=0,right=n-1; int i; //循环条件一定要注意 while(left<=right){ //此处的mid的计算一定要放在while循环内部,否则mid无法正确更新;并且此处用移位代替除以2可以提高效率,而且可以防止溢出。 int i=left+((right-left)>>1); if(x>a[i]) left=i+1; else if(x<a[i]) right=i-1; else return i; } //执行流如果走到此处说明没有找到要查找的数字。 return -1;}
注意:
right=n-1
——>while(left<=right)
——>right=i-1
right=n
——>while(left<right)
——>right=i
大部分人喜欢在最开始就判断arr[mid]与x相等,但是这样是不明智的,因为相等情况在大多状况下都是少数,写在开始的话,每次循环都需要判断一次相等,浪费时间,效率太低。
复杂度渐进表示法
不同函数复杂度
复杂度分析小窍门
若两段算法分别有复杂度
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))
若
T(n)是关于n的k阶多项式,那么T(n)=Θ(nk) 一个for循环的时间复杂度等于循环次数乘以循环体代码的复杂度
if-else结构的复杂度取决于if的条件判断复杂度和两个分支部分的复杂度,总体复杂度取三者中最大
应用实例:最大子列问题
例题:
算法1
int MaxSubseqSum1(int A[],int N){ int ThisSum,MaxSum=0; int i,j,k; for(i=0;i<N;i++){ //i是之列的左端位置 for(j=i;j<N;j++){ //j是子列右端位置 ThisSum=0; //ThisSum是从A[i]到A[j]的子列和 for(k=i;k<=j;k++) ThisSum+=A[k]; if(ThisSum>MaxSum) //如果刚得到的这个子列和更大 MaxSum=ThisSum; //则更新结果 } //j循环结束 } //i循环结束 return MaxSum;}
时间复杂度:
算法2
int MaxSubseqSum2(int A[],int N){ int ThisSum,MaxSum=0; int i,j; for(i=0;i<N;i++){ //i是之列的左端位置 ThisSum=0; //ThisSum是从A[i]到A[j]的子列和 for(j=i;j<N;j++){ //j是子列右端位置 //对于相同的i,不同的j,只要在j-1次循环的基础上累加一项即可 ThisSum+=A[j]; if(ThisSum>MaxSum) //如果刚得到的这个子列和更大 MaxSum=ThisSum; //则更新结果 } //j循环结束 } //i循环结束 return MaxSum;}
时间复杂度:
算法3:分而治之
int Max3( int A, int B, int C ) // 返回3个整数中的最大值{ return A > B ? A > C ? A : C : B > C ? B : C;} //分治法求List[left]到List[right]的最大子列和int DivideAndConquer( int List[], int left, int right ){ int MaxLeftSum, MaxRightSum; //存放左右子问题的解 int MaxLeftBorderSum, MaxRightBorderSum; //存放跨分界线的结果 int LeftBorderSum, RightBorderSum; int center, i; if( left == right ) //递归的终止条件,子列只有1个数字 if( List[left] > 0 ) return List[left]; else return 0; //下面是"分"的过程 center = ( left + right ) / 2; //找到中分点 //递归求得两边子列的最大和 MaxLeftSum = DivideAndConquer( List, left, center ); MaxRightSum = DivideAndConquer( List, center+1, right ); //下面求跨分界线的最大子列和 MaxLeftBorderSum = 0; LeftBorderSum = 0; //从中线向左扫描 for( i=center; i>=left; i-- ) { LeftBorderSum += List[i]; if( LeftBorderSum > MaxLeftBorderSum ) MaxLeftBorderSum = LeftBorderSum; } // 左边扫描结束 MaxRightBorderSum = 0; RightBorderSum = 0; //从中线向右扫描 for( i=center+1; i<=right; i++ ) { RightBorderSum += List[i]; if( RightBorderSum > MaxRightBorderSum ) MaxRightBorderSum = RightBorderSum; } //右边扫描结束 //下面返回"治"的结果 return Max3( MaxLeftSum, MaxRightSum, MaxLeftBorderSum + MaxRightBorderSum ); } int MaxSubseqSum3( int List[], int N ) //保持与前2种算法相同的函数接口 { return DivideAndConquer( List, 0, N-1 ); }
时间复杂度:
算法4:在线处理
int MaxSubseqSum1(int A[],int N){ int ThisSum,MaxSum; int i,j; ThisSum=MaxSum=0; for(i=0;i<N;i++){ ThisSum+=A[j]; //向右累加 if(ThisSum>MaxSum) //如果刚得到的这个子列和更大 MaxSum=ThisSum; //则更新结果 else if(ThisSum<0) //如果当前子列和为负 ThisSum=0; //则不可能使后面的部分和增大,抛弃之 } return MaxSum;}
时间复杂度:
“在线”的意思是指每输入一个数据就进行即时处理,在任何一个地方中止输入,算法都能正确给出当前的解。
- (笔记)数据结构第一讲-基本概念
- 陈越《数据结构》第一讲 基本概念
- 陈越、何钦铭《数据结构》第一讲基本概念 笔记
- 网易云课堂-数据结构-第一讲-基本概念
- 数据结构——第一讲、基本概念(1)
- 数据结构——第一讲、基本概念(2)
- 数据结构——第一讲、基本概念(3)
- 第一讲 基本概念
- 第一讲 基本概念
- 浙江大学公开课-数据结构第一讲笔记
- 数据结构 第一讲
- 数据结构第一讲
- Servlet 第一讲 笔记
- CCNA第一讲笔记
- C++笔记 第一讲
- 第一讲数据结构(2)
- 数据结构第一讲-复杂度问题
- 第一讲 Android 屏幕适配基本概念
- 由Combination Sum I II 不懂的地方
- ABBYY finereader 12 激活码-破解版-注册机
- Java学习笔记(4)
- Python实现抽象基类的3三种方法
- 第三课作业2:100以内全部素数
- (笔记)数据结构第一讲-基本概念
- IntelliJ IDEA使用教程SVN的集成与使用
- Python3.4.3中使用imageio库png合成gif
- python的elementtree模块处理中文注意事项
- ASP.NET Core 2.0 开源Git HTTP Server
- 解析内部类
- this易错点
- 15算法课程 122. Best Time to Buy and Sell Stock II
- MongoDb在线文档