您的位置:首页 > 理论基础 > 数据结构算法

数据结构:递归 算法分析

2007-05-21 13:29 232 查看
使用递归的四个法则:

      1.基准情形(Base case):必须总有某种基准情形,它无须递归就能解出.
      2.不断推进(Making progress):对于那些需要递归求解的情形,每一次递归调用都必须要使求解状况朝接近基准的情形的方向推进.
      3.设计法则:假设所有的递归调用都能运行.
      4.合成效益法则:在求解一个问题的同一实例时,切勿在不同的递归调用中做重复性的工作.

关于算法运行时间的几个法则:

      法则1-For 循环:
                 一次For循环的运行时间至多是该For循环内语句(包括测试)的运行时间乘迭代的次数.
                 example 01 O(N):
                           for(int i=0;i<n;i++)
                                    printf("%d",i);
                                    
      法则2-嵌套的For循环:
                 从里向外分析这些循环,在一组嵌套循环内部的一条语句的运行时间为该语句的运行时间乘以该组所有的for循环的大小的乘积.
                  example 02 O(N2):
                           for(int i=0;i<n;i++)
                                 for(int j=0;j<n;j++)
                                       printf("%d",j)

      法则3-顺序语句:
                 将各个语句的运行时间求和即可(这意味着,其中最大的值就是所得的运行时间)
                  example 03 O(N2)
                           for(i=0;i<n;i++)
                                   a[i]=i;
                           for(i=0;i<n;i++)
                                 for(j=0;j<n;j++)
                                    a[i]+=a[j]+1

      法则4-IF ELSE语句:
                 一个IF/ELSE语句的运行时间从不超过判断再加上S1和S2中运行时间长者的总的运行时间.
                  if(Condition )
                        S1
                  else
                        S2

两个递归的漂亮应用:

   1. 最大子序列和问题:O(NlogN)
       static int MaxSubSum(const int a[],int Left,int Right)
        {
            int MaxLeftSum,MaxRightSum;
            int MaxLeftBorderSum,MaxRightBorderSum;
            int LeftBorderSum,RightBorderSum;
            int Center,i;
            
            //Base case
            if(Left == Right)
                     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);
         
            MaxLeftBorderSum = 0; LeftBorderSum =0;
            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(MaxRightSum,MaxLeftSum,MaxLeftBorderSum+MaxRightBorderSum);
         }
           
       int MaxSubsqeenceSum(const int a[],int n)
         {
               return MaxSubSum(a,0,n-1);
         } 

     2. 幂运算:O(logN)
         long int Pow(long int x,int n)
         {
            //Base case
              if(n=0)
                     return 1;
              if(n=1)
                     return n;
              if(IsEven(N))
                     return Pow(x*x,n/2);
              else
                     return Pow(x,n-1)*x;
         }

两个经典算法:

   1.二分查找:O(logN)
      int BinarySearch(const ElementType a[],Element x,int n)
      {
            int low,mid,high;
            low =0;high = n-1;
            while(low<=high)
            {
                  mid=(high-low)/2;
                  if(a[mid] > x)
                        low = mid+1;
                  else
                        if(a[mid]<x)
                              high = mid-1;
                        else
                              return mid;
             }
             return -1;
      }

     2.欧几德时算法,求两个数的最多公因数Gcd: O(logN)
         int Gcd(int m,int n)
           {
                     int rem;
                     while(n>0)
                     {
                                rem = m%n;
                                m=n;
                                n=rem;
                     }
4000

                     return m;
           }
 

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息