(笔记)数据结构第一讲-基本概念

来源:互联网 发布:脸部黄金比例测试软件 编辑:程序博客网 时间:2024/04/28 18:49

第一讲 基本概念

空间复杂度S(n)

根据算法写成的程序在执行时占用储存单元的长度。

时间复杂度T(n)

根据算法写成的程序在执行时耗费时间的长度。

例题1
void Print(int N){    if(N){        Print(N-1);        printf("%d\n",N);    }    return;}
物理存储:每递归一次需要申请一个方法临时变量的储存内存
100000 99999 99998 …… 1 ……
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相等,但是这样是不明智的,因为相等情况在大多状况下都是少数,写在开始的话,每次循环都需要判断一次相等,浪费时间,效率太低。


复杂度渐进表示法

T(n)=O(f(n))C>0,n0>0使n>=n0T(n)<=Cf(n) (上界)

T(n)=Ω(g(n))C>0,n0>0使n>=n0T(n)>=Cg(n) (下界)

T(n)=Θ(h(n))T(n)=O(h(n))T(n)=Ω(h(n)) (既是上界也是下界)

不同函数复杂度

复杂度分析小窍门

  • 若两段算法分别有复杂度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)nkT(n)=Θ(nk)

  • 一个for循环的时间复杂度等于循环次数乘以循环体代码的复杂度

  • if-else结构的复杂度取决于if的条件判断复杂度和两个分支部分的复杂度,总体复杂度取三者中最大


应用实例:最大子列问题

例题:N{A1,A2,...,AN},f(i,j)=max{0,jk=1Ak}

算法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;}

时间复杂度:T(N)=O(N3)

算法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;}

时间复杂度:T(N)=O(N2)

算法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 );  }  

时间复杂度:T(N)=2T(N/2)+cN,T(1)=O(1)

         =2[2T(N/22)+cN/2]+cN

         =2kO(1)+ckN    N/2k

         =NO(1)+clog2N×N

         =O(NlogN)

算法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;}

时间复杂度:T(N)=O(N)

“在线”的意思是指每输入一个数据就进行即时处理,在任何一个地方中止输入,算法都能正确给出当前的解。

原创粉丝点击