• 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;

  • 相关阅读:
    c#多线程和Socket笔记
    Socket测试工具包的开发(TCP UDP)
    使用socket模拟服务器给客户端发消息
    AU3学习笔记
    c#委托与事件(三)
    c#委托与事件(二)
    使用的工具
    Zip 压缩问题件,获取真实扩展名
    PsExec使用
    socket 통신
  • 原文地址:https://www.cnblogs.com/qichunlin/p/8922416.html
Copyright © 2020-2023  润新知