数据结构(Java语言版)
上QQ阅读APP看书,第一时间看更新

1.2 算法的概念

1.2.1 算法的定义

算法是对问题求解的步骤描述。

➢ 举例1:学生进行入学报到时,一般按照在X处注册缴费、在Y处安排住宿、在Z处集合领教材等流程办理入学手续,不能住宿费、学费还没有缴就办理住宿、领教材,直接去上课了,这在原则上是不允许的。在这个例子中,学生的执行流程体现了算法的执行步骤。

➢ 举例2:作者要完成本教材的编写,首先要进行市场调研,了解目前流行的教材的特点和高校开设这门课程的情况,研究存在的问题;然后构思如何编写一本通俗易懂且实用的教材以及如何在课堂教学中实施;接下来就是编写目录、框架;再接下来就是查阅和收集众多参考文献及素材;最后花大量时间和精力去撰写内容,并反复检查、打磨和优化。倘若作者不了解市场而盲目编写,则不会写出受读者欢迎的书。在这个例子中,作者怀揣情怀编写一本付出心血的教材体现了算法的执行步骤。

算法处处皆在,读者思想驰骋,能否信手拈来?

1.2.2 算法的特性

算法具有以下5个特性。

1. 有穷性

算法是由若干条指令组成的有穷序列,而非永不停止。在下面的算法1.1中,while(true)是“永动机”,循环永远跳不出来,导致后面的语句无法执行(事实上,打开注释后报错“语句不可达”),注释调整之后,该算法具有有穷性。

2. 确定性

算法的每一条语句有特定的含义,无歧义。在算法1.1中,x和y求和,以及整型z转换为字符串outPut,含义明确,具有确定性。

3. 可行性

算法在当前环境条件下可以通过有限次运算实现。算法1.1的algorithm1_1()方法经过有限次运算能够实现。

4. 输入性

算法有零个或多个输入。算法1.1的algorithm1_1()方法有2个输入参数,在设计算法时也可以没有输入参数或有更多的输入参数。

5. 输出性

算法有一个或多个输出。算法1.1的algorithm1_1()方法带返回类型。一般地,算法都有输出;若输出有多个,则在程序设计时可以把多个输出放到集合中再逐个输出。

【算法1.1】理解算法的5个特性。具体代码如下。

public String algorithm1_1(int x, int y) { //输入性:2个输入参数
   //while(true){}                         //无穷性:破坏了算法后续语法
     for (int i = 1; i <= 10; i++) {      //有穷性:算法运行时间有限
          System.out.println(" 先循环10次再说" + i);
     }
     int z = x + y;                        //确定性:语法没问题
     String outPut = z + "";               //确定性:语法没问题
     return outPut;                        //输出性:1个输出
}                                          //可行性:运行之后能实现

1.2.3 算法设计目标

算法设计目标,就是设计出好的算法。好的算法可达到以下5个目标。

1. 正确性

算法能够满足具体问题的需求,程序运行正常,通过测试能够达到预期目标。

2. 健壮性

算法对非法数据和操作有处理机制。

3. 易读性

算法遵循标识符命名规则,简洁易懂,适当注释,方便阅读和理解,也便于后期维护和扩展。

4. 高效性

算法运行的时间短。

5. 低存储性

算法所需的存储空间低。

前3个是算法的基本要求,后2个是好算法的评判标准。

1.2.4 算法描述

算法描述是指对问题求解过程的描述。算法可采用自然语言、程序设计语言、伪代码来描述。

1. 用自然语言描述

用自然语言描述即接近口头描述。用自然语言描述算法简单易懂,但严谨性较差。

2. 用程序设计语言描述

程序设计语言如Java、C#、Python等。用某种具体的程序设计语言来描述算法较严谨,算法可直接在计算机上执行,但非专业人士难以理解。

3. 用伪代码描述

伪代码介于自然语言和程序设计语言之间。用伪代码描述算法可以忽略严格的语法规则,便于用户理解,且容易将其转换为用程序设计语言描述的算法。

举例:根据学号查找学生。

(1)用自然语言描述:从学号列表第1个元素开始,与给定学号进行比较,若相等则查找成功,若不相等则比较下一个元素,直到最后一个元素比较完。这个过程要么查找成功,要么查找失败。(2)用程序设计语言描述:如算法1.2。

【算法1.2】用程序设计语言描述算法。具体代码如下。

public int algorithm1_2(int key) {               //key为给定学号
    int[] studentNo = {101, 102, 103, 104, 105}; //学号列表
    for (int i = 0; i < studentNo.length; i++)
        if (studentNo[i] == key)                 //比较
             return 1;                           //查找成功
     return 0;                                   //查找失败
}

(3)用伪代码描述,如下所示。

key = 100
for(学号in学号列表)
{
     if(学号 == key)
          查找成功,结束
}
查找失败,结束