欢迎来到算法的世界!

你好!今天我们将深入探讨计算机科学中最重要的部分之一:算法(Algorithms)。别被这个名词吓倒了——算法其实就是为了解决问题或完成任务而设计的一系列步骤指令。无论是你跟着食谱烤蛋糕,还是告诉朋友怎么去你家,你在日常生活中其实已经在使用算法了!

在本章中,我们将学习如何设计这些指令,让计算机能够理解它们,学习如何找出错误,以及如何让我们的解决方案运行得尽可能快。

1.1 构建基础:分解与抽象

在编写算法之前,我们需要像计算机科学家一样思考。我们通过计算思维(Computational Thinking)来做到这一点。其中两个最重要的工具是分解(Decomposition)抽象(Abstraction)

分解

分解是指将复杂的问题拆解成较小、较易处理的部分。
例子: 如果你想制作一款电子游戏,你不会只是“编写游戏”。你会把它拆解为:1. 角色移动、2. 计分系统、3. 图像显示,以及 4. 音效。解决四个小问题比解决一个大问题要容易得多!

抽象

抽象是指移除不必要的细节,将焦点放在重要的部分上。
例子: 看看伦敦地铁图。它不会显示每一条街道或建筑物,它只显示车站和路线。通过抽象化那些额外的细节,地图变得更容易使用。

子程序

子程序(Subprogram)是一小段用来执行特定任务的程序代码,可以在需要时随时“调用”它。
子程序的好处:
• 你不需要重复编写相同的程序代码。
• 它使程序更容易阅读和测试。
• 不同的人可以同时编写不同的子程序。

快速回顾:分解 = 拆解问题。抽象 = 简化信息。子程序 = 可重用的代码块。

1.2 算法的表示方式

在我们我们将算法输入计算机之前,主要有两种“绘制”或“编写”算法的方法:流程图(Flowcharts)伪代码(Pseudocode)

流程图

流程图使用不同的形状来显示程序执行的路径。以下是你必须知道的形状:
椭圆形(终止符): 用于“开始”和“结束”。
平行四边形: 用于输入(例如:询问姓名)和输出(例如:显示结果)。
矩形: 用于处理(例如:像 \(x = y + 2\) 这样的运算)。
菱形: 用于决策(例如:“分数是否大于 50?”)。这个形状总是有两个箭头伸出:一个用于“是/真(Yes/True)”,另一个用于“否/假(No/False)”。

伪代码

伪代码是一种编写指令的方式,它看起来像程序语言,但使用的是平实的英文。它没有严格的“文法”规则,所以你不必担心漏掉分号!
例子:
OUTPUT "请问你的年龄是多少?"
INPUT userAge
IF userAge >= 18 THEN OUTPUT "你可以投票!"

1.3 程序设计结构

世界上每一个算法都是由三种基本结构构建而成的:

1. 顺序(Sequence): 按特定的顺序,一个接一个地完成指令。
2. 选择(Selection): 使用 IFTHENELSE 进行选择。
3. 迭代(重复,Iteration): 多次循环执行指令。有两种类型:
    • 计数控制: 当你知道确切重复次数时使用(例如:FOR 循环)。
    • 条件控制: 当你希望重复执行直到某个条件改变时使用(例如:WHILE 循环)。

关键总结: 每个程序都只是步骤(顺序)、选择(选择)和循环(迭代)的组合。

1.4 运算符与数据

为了进行运算和决策,我们使用运算符(Operators)。可以把这些想象成你算法中的“动词”。

算术运算符

这些用于数学运算:
加法: \(+\)
减法: \(-\)
乘法: \(*\)
除法: \(/\)
整除(DIV): 告诉你一个数字能被另一个数字除几次,并忽略余数(例如:\(7 \text{ DIV } 2 = 3\))。
取模(MOD): 只告诉你余数(例如:\(7 \text{ MOD } 2 = 1\))。
指数: \(^\)(例如:\(2 ^ 3 = 8\))。

关系与逻辑运算符

这些帮助计算机进行决策:
关系: ==(等于)、!=(不等于)、<(小于)、>(大于)。
逻辑: AND(两者必须同时为真)、OR(至少一个为真)、NOT(反转结果)。

常见错误: 不要混淆 ===。在许多程序语言中,单个 = 用于设定数值(赋值),而 == 则是询问“它们相等吗?”(比较)。

1.5 寻找与修正错误

即使是最优秀的程序员也会犯错!你需要知道以下三种错误类型:

1. 语法错误(Syntax Error): 程序代码中的“文法”错误(例如:将 PRINT 拼写为 PRUNT)。程序将无法启动。
2. 逻辑错误(Logic Error): 程序可以执行,但给出的答案是错误的。例如,你想将两个数字相加,却不小心输入了减号。
3. 运行时错误(Runtime Error): 程序在执行过程中发生的错误,导致崩溃(例如:要求计算机除以零)。

追踪表

追踪表(Trace Table)是一种用来追踪变量数值的工具,当你逐行执行算法时,它可以帮助你找出逻辑错误
如何使用: 为每个变量建立一个栏位,并为输出建立一个栏位。每次程序代码改变数值时,就更新对应的栏位。

1.6 标准算法:搜索与排序

你需要理解这四个经典算法是如何运作的。想象一下你有一叠乱序的试卷,你需要找到某位学生的试卷,或者按字母顺序排列它们。

搜索算法

1. 线性搜索(Linear Search): 你从头到尾一个一个地查看列表中的每个项目。它适用于任何列表,但对于大型数据集来说速度很慢。
2. 二分搜索(Binary Search): 快得多!你直接跳到列表的中间。如果你要找的项目比中间值小,就丢弃右半部分;如果更大,就丢弃左半部分。重复此过程直到找到为止。
重要事项: 二分搜索适用于已经排序过的列表。

排序算法

1. 冒泡排序(Bubble Sort): 你比较相邻的两个项目,如果顺序不对就交换它们。你不断地在列表中“循环扫描”,直到不需要再进行任何交换为止。
2. 合并排序(Merge Sort): 一种“分而治之”的算法。你将列表拆分为单个项目,然后将它们按正确顺序合并起来。这对于大型列表来说非常快!

记忆小撇步: “线性(Linear)”就像一条线(line);“二分(Binary)”就像二分法(bi-secting,切成两半)

1.7 算法效率

我们如何知道一个算法是否“好”?我们基于以下两点评估其效率
时间: 需要多少次比较扫描
空间: 使用了多少内存

例子: 二分搜索比线性搜索更有效率,因为它通常只需更少的步骤就能找到答案。

关键总结: 不仅要找到解决方案,更要找到最快最简洁的解决方案!