数据结构-算法以及算法分析

数据结构算法以及算法分析

1.什么是算法?

其实在学C、C++、Java的过程中你已经接触了它,但是你可能从来没有听说过它,它就是你在写程序之前,脑子中构思的东西。
算法(Algorithm):是解决问题的方法和步骤。是对某一特定问题求解步骤的描述,它是指令的有限序列。
例如,在数组上实现选择排序的算法
思路:用嵌套双循环实现,
①外循环for(i=1;i ②内循环for(j=i;j<=n;j++)找出最小值下标k,如果k与i不等交换两个元素

2.算法有以下几个特性:

⑴ 输入(Input):算法有0个或多个输入
⑵ 输出(Output):算法至少有1个或多个输出
⑶ 明确性(Definiteness):算法的每一步都有确定的含义,不存在二义性
⑷ 有限性(Finiteness):算法在有限的步骤之后会自动停止运行而不会无限循环运行,并且每个步骤都可以在可接受的时间内完成
⑸ 可行性(Effectiveness):算法的每一步都是可行的,也就是说每一步都能够执行有限的次数完成

3.算法设计的要求(好的算法应达到以下目标)

⑴ 正确性(Correctness):算法的正确性是指算法至少应该具有输入、输出和加工处理无歧异性、能正确反映问题的需求、能够得到问题的正确答案。

          正确性分以下四个层次:
          1)算法程序没有语法错误
          2)算法程序对于合法的输入数据能够产生满足要求的输出结果。
          3)算法程序对于非法的输入数据能够得出满足规格说明的结果。
          4)算法程序对于精心选择的,甚至刁难的测试数据都有满足要求的输出结果

⑵ 可读性(Readability):算法设计的另一目的是为了便于阅读、理解和交流。
⑶ 健壮性(Robustness):当输入数据不合法时,算法也能做出相关处理,而不是产生异常或莫名其妙的结果。
⑷ 高效率低存储量:执行时间短的算法效率高,存储量需求是指算法在执行过程中需要的最大存储空间。

效率:对于同一个问题,如果有多个算法可以解决,执行时间短的算法效率高,执行时间长的效率低。
存储量:存储量需求指的是算法在执行的过程中需要的最大存储空间,主要指算法程序运行时所占用的内存或外部硬盘存储空间。

好的算法,当然应该四者兼备。

4.算法描述

算法有不同的语言描述实现版本,如C语言,Python语言,C++语言等。
这里采用类C语言代码来表示算法,它是标准C语言的扩充。

预定义常量: MAXSIZE 、SUCCESS 、 TRUE、 FALSE、 ERROR

   #define MAXSIZE  1000
   #define TRUE     1
   #define FALSE    0
   #define ERROR    0

类型定义说明

typedef 定义具体数据结构类型。
例如:定义一个结构体类型student

     typedef struct {        
                        char name[20];
                        int   data[3];
                        float average;
                     }student;

算法描述-------函数形式描述;

     [数据类型] 函数名([形式参数及说明])
        { 内部数据说明;
          执行语句组;
        }

3 赋值语句

简单赋值:

    变量名1=表达式;

成组赋值:

       (变量名1,…,变量名n)=(表达式1,…,表达式n);
       结构名1=结构名2;
       变量名[  ]=表达式;
       变量名[下标1..下标2]=变量名[下标3..下标4];
       结构名={表达式1,表达式2,… 表达式n};
       变量名[n]={值1,值2,…,值k};

串联赋值:

    变量名1=变量名2=…=表达式;

⑸ 分支语句

      1. if(条件表达式) 语句;
      2. if(条件表达式) 语句1;    else   语句2; 
      3. swith(表达式)
         {  case 值1:语句1;break;
            case 值2:语句2;break; 
              ……
            case 值n:语句n;break;
            [default:语句n+1; ]
         }

要善用switch结构,来简化多重条件和嵌套条件,使多分支结构清晰。
方括号括起来的部分如“[default:语句n+1;]”为可选项。

⑹ 循环语句

① for(赋值表达式;条件表达式;修改表达式)循环体语句;
② while(条件表达式)语句;
③ do 语句; while(条件表达式);【do while】

⑺ 结束语句

① return<表达式>;或return;用于函数结束。
② break语句:可用于循环语句中循环过程结束或跳出情况;switch语句中结束或跳出情况语句
③ continue语句:可用在循环语句中结束本次循环过程,进入下一次循环过程
④ exit语句:表示出现异常情况时,控制退出函数。

5.算法分析

⑴ 算法的时间复杂度

算法在机器上执行的时间,通常是从算法中选取一种对于研究的问题来说是基本运算的原操作,以该基本操作要 执行的次数,或称为语句的频度作为算法的时间量度。
记作: T(n)=O(f(n))。它表示随问题规模 n的增大算法执行时间的增长率和 f(n)的增长率相同,称作算法的渐进时间复杂度,简称为时间复杂度。其中 f(n)是问题规模 n的某个函数。

计算方法:

1.用常数1取代函数中所有的常数
2.只保留最高项
3.最好情况时间复杂度:代码在最坏情况下执行的时间复杂度。

常用的时间复杂度所耗费的时间从小到大依次是
O(1) < O(log n) < O(n) < O(nlog n) < O(n2) < O(n3) < O(n!) < O(nn)

一般法则

法则 1-----for循环
一次for循环的运行时间至多是该for循环内语句的运行时间X循环的次数。

  for(i = 1 ; i <= n ; i++)
  {
      x = x + 1;        /* 时间复杂度为O(n) */
  }

法则 2-----嵌套的for循环
从里向外分析,在一组嵌套循环内部的一跳语句总的运行时间为该语句的运行时间X该组所有for循环的大小的乘积。

 for( i = 0; i < n; i++)
 {
     for(j = 0; j < n; j++)
          k++;      /* 时间复杂度为O(n*n) */
 }

法则 3-----顺序语句
将各个语句的运行时间求和即可,其中的最大值即为运行时间。

 for(i = 1 ; i <= n ; i++)
 {
     x = x + 1;     /* 时间复杂度为O(n) */
 }
 for( i = 0; i < n; i++)
 {
     for(j = 0; j < n; j++)
        k++;        /* 时间复杂度为O(n*n) */
 }
 /* 总时间复杂度为O(n*n) */

法则 4-----while语句

int count = 1;
while(count < n){
    count *= 2;
    /*时间复杂度为 O(1) 的程序步骤序列*/
}

/* 2^x = n 时间复杂度为O(log n) */

(2)空间复杂度

一个程序执行时,除了需要寄存本身所用的指令、常数、变量和输入数据以外,还需要辅助存储空间的多少 。
算法的空间复杂度是通过计算算法所需的存储空间实现
算法空间复杂度的计算公式记作: S(n)=O(f(n))S(n)=O(f(n)) S(n) = O(f(n))S(n)=O(f(n)) 。其中,n 为问题的规模, f(n)f(n) f(n)f(n) 为语句关于 n 所占存储空间的函数。

(3)递归:

  int F(int x)
  {
      if(x == 0)
          retuen 0;
      else 
          return 2 * F(x-1) + X * X;
  }
1.它是否就是循环逻辑?

答案是:虽然函数会用到这个函数本身,但是我们并没有用函数本身来定义函数的一个特定的实例。即使用F(5)来得到F(5)的值才是循环,通过F(4)来得到F(5)的值不是循环的。

2.实现递归的基本准则:

基准情形:递归中必须要有某些基准情形,他们不用递归就能求解。

不断推进:对于那些需要递归求解的情形,递归调用必须总能朝着产生基准情形的方向推进。

设计法则:假设所有的递归调用都能运行。

合成效益法则:在求解一个问题的同一实例时,切勿在不同的递归调用中做重复性的工作。

作者在算法和算法分析中借鉴了CSDN中的一位博主,下面附上原链接:https://blog.csdn.net/weixin_44988083/article/details/97542282

你可能感兴趣的:(数据结构-算法以及算法分析)