2018.4.23 数据结构

算法:
计算=信息处理 借助某种工具,遵照一定规则,以明确而机械的形式进行

计算模型=计算机=信息处理工具

所谓算法,旨在解决特定问题的指令序列     
        输入:待处理的信息(问题)
        输出:经处理的信息(答案)
        正确性:的确可以解决指定的问题
        确定性:任以算法都可以描述为一个由基本操作组成的序列
        可行性:每一基本操作都可实现,且在常熟时间内完成
        有穷性:对于任何输入,经过有穷次基本操作,都可以得到输出  
         .....

Hailstone(n)={ 
                 {1}                      n<=1  
                 {n} 并 Hailstone(n/2)    n 偶
                 {n} 并 Hailstone(3n+1)   n 奇
             }
 
int hailstone(int n)//计算序列hailstone(n)的长度
{
      int length=1;//从1开始,以下按定义逐步递推,并累计步数,直至n=1
      while(1<n)
      {
          (n%2)? n=3*n+1:n/=2;
          length++;
          return length;//返回hailstone
      }

 好算法:
      正确:符合语法,能够编译,链接
            能够正确处理简单的输入
            能够正确处理大规模的输入
            能够正确处理一般性的输入
            能够正确处理退化的输入
            能够正确处理任意合法的输入

       健壮:能辨别不合法的输入并做适当处理,而不致非正常退出

       可读:结构化+准确命名+注释+...

       效率:速度更可能快;存储空间尽可能少

       data Structure +Algorithm(算法)  简称 DSA    

        RAM:Random Access Machine 

 算法分析:
     正确性

     成本:运行时间+所需存储空间

     上溢:当一个超长的数据进入到缓冲区时,超出的部分被写入到上级缓冲区,上级缓冲区,

上级缓冲区存放的可能是数据,上一条指令的指针,或者是其他程序的输出内容,这些内容被覆盖或
者破坏掉。

      下溢:当一个超长的数据进入到缓冲区时,超出的部分被写入下级缓冲区,下级缓冲区存放

的是下一条指令的指针,或者是其他程序的输出内容。

起泡排序:
     void bubblesort(int A[],int n)
     {
          for(bool sorted=false;sorted=!sorted;n--)//逐趟扫描交换,直至完全有序
              for(int i=1;i<n;i++)//自左向右,逐对检查A[0,n)内各相邻元素
                 if(a[i-1]>a[i])
                 {
                    swap(A[i-1],A[i]);//令其互换
                    sorted=false;//清除(全局)有序标志  
                 }

      }
 不变性:经过K轮扫描交换后,最大的K个元素必然就位
 单调性:经K轮扫描交换后,问题规模缩减至n-k
 正确性:经至多n趟扫描后,算法必然终止,且能给出正确解答

计算n个整数之和:
  int sunI(int A[],int n)    E2
  {
       int sum=0;
       for(int i=0;i<n;i++)
          sum+=A[i];
          return sum;
  }

  减而治之:为求解一个大规模的问题,可以将其划分为两个子问题,其一是平凡,另一规模缩

减(//单调性),分别求解子问题,由子问题的解,得到原问题的解。

 数组求和:线性递归
  sum(int A[],int n)
  {
        return 

        (n<1) ?

         0:sum(A,n-1)+A[n-1];
  }

  数组倒置:任给数组A[0,n),将其前后颠倒
  统一接口:void reverse(int *A,int lo,int hi);
  递归版:
       if(lo<hi)//问题规模的奇偶性不变,需要两个递归基     E5
        { 
            swap(A[lo],A[hi]); reverse(A,lo+1,hi-1);
         }
  迭代原始版:
        next:
          if(lo<hi)
          {
              swap(A[lo],A[hi]);lo++;hi--;goto next;
           }
  迭代精简版:
         while(lo<hi) swap(A[lo++],A[hi--]);

  分而治之:
      为求解一个更大规模的问题,可以将其划分为若干(通常2个)子问题,规模大体相当

分别求解子问题,由子问题的解,得到原问题的解。

  数组求和:二分递归
  sum(int A[],int lo,int hi)//区间范围A[lo,hi]
  {
       if(lo==hi)   return A[lo];
       int mi=(lo+hi)>>1;//右移,也相当于除2
       return sum(A,lo,mi)+sum(A,mi+1,hi)
   }//入口形式为sum(A,0,n-1)

   迭代1:从数组区间A[lo,hi)中找出最大两个整数A[x1]和A[x2]元素比较次数,要求尽可能地少
   void max2(int A[],int lo,int hi,int &x1,int &x2)//1<n=hi+lo  
   {
         for(x1=lo,int i=lo+1;i<hi;i++)//扫描A[lo,hi),找出A[x1]
            if(A[x1]<A[i])   x1=i;//hi-lo-1=n-1
         for(x2=lo,int i=lo+1;i<x1;i++)  //扫描A[lo,x1)
            if(A[x2]<A[i])   x2=i;// x1-lo-1
         for(int i=x1+1;i<hi;i++)//再扫描A(x1,hi),找出A[x2]
            if(A[x2]<A[i])   x2=i;//hi-x1-1
    }   
    迭代2:问题同上
    void max2(int A[],int lo,int hi,int &x1,int &x2)//1<n=hi+lo 
    {
          if(A[x1=lo]<A[x2=lo+1])   swap(x1,x2);
          for(int i=lo+2;i<hi;i++)
             if(A[x2]<A[i])
               if(A[x1]<A[x2=i])
                  swap(x1,x2);
     }
     递归+分治:问题同上
     void max2(int A[],int lo,int hi,int &x1,int &x2)
      {
         if(lo+2==hi)  { /*.....*/; return; }//T(2)=1
         if(lo+3==hi)d

00000000 { /...../; return; }//T(3)<=3
int mi=(lo+hi)/2; //divide
int x1L,x2L; max2(A,lo,mi,x1L,x2L);
int x1R,x2R; max2(A,mi,hi,x1R,x2R);
if(A[x1L]>A[x1R])
{
x1=x1L;x2=(A[x2L]>A[x1R])? x2L:x1R;
}else
{
x1=x1R; x2=(A[x1L]>A[x2R])? x1L : x2R;
}//1+1=2
}
动态规划: XC3
fib():迭代
动态规划:颠倒计算方向,由自顶而下递归,为自底而上迭代
f=0; g=1;//fib(0),fib(1)
while(0<n--)
{
g=g+f;
f=g-f;
}
return g;

posted @ 2018-04-23 22:49  LegendQi  阅读(295)  评论(0编辑  收藏  举报