算法是程序的灵魂,让我们从基础开始
算法是程序的灵魂,只有掌握了算法,才能轻松地驾驭程序开发。软件开发工作不是按部就班,而是选择一种最合理的算法去实现项目功能。算法能够引导开发者在面对一个项目功能时用什么思路去实现,有了这个思路后,编程工作只需要遵循这个思路去实现即可。本章将详细讲解计算机算法的基础知识,为读者步入后面的学习打下基础。
1.1 算法的基础
自然界中的很多事物并不是独立存在的,而是和许多其他事物有着千丝万缕的联系。就拿算法和编程来说,两者之间就有着必然的联系。在编程界有一个不成文的原则,要想学好编程,就必须学好算法。要想获悉这一说法的原因,先看下面对两者的定义。
算法是一系列解决问题的清晰指令,算法代表着用系统的方法描述解决问题的策略机制。也就是说,能够对符合一定规范的输入,在有限时间内获得所要求的输出。如果一个算法有缺陷,或不适合于某个问题,执行这个算法将不会解决这个问题。不同的算法可能用不同的时间、空间或效率来完成同样的任务。
编程是让计算机为解决某个问题而使用某种程序设计语言编写程序代码,并最终得到结果的过程。为了使计算机能够理解人的意图,人类就必须将需要解决的问题的思路、方法和手段通过计算机能够理解的形式“告诉”计算机,使计算机能够根据人的指令一步一步去工作,完成某种特定的任务。编程的目的是实现人和计算机之间的交流,整个交流过程就是编程。
在上述对编程的定义中,核心内容是思路、方法和手段等,这都需要用算法来实现。由此可见,编程的核心是算法,只要算法确定了,后面的编程工作只是实现算法的一个形式而已。
1.1.1 算法的特征
在1950年,算法(Algorithm)一词经常同欧几里得算法联系在一起。这个算法就是在欧几里得的《几何原本》中所阐述的求两个数的最大公约数的过程,即辗转相除法。从此以后,算法这一叫法一直沿用至今。
随着时间的推移,算法这门学科得到了长足的发展,算法应该具有如下5个重要的特征。
有穷性:保证执行有限步骤之后结束。
确切性:每一步骤都有确切的定义。
输入:每个算法有零个或多个输入,以刻画运算对象的初始情况。所谓零个输入,是指算法本身舍弃了初始条件。
输出:每个算法有一个或多个输出,显示对输入数据加工后的结果,没有输出的算法是毫无意义的。
可行性:原则上算法能够精确地运行,进行有限次运算后即可完成一种运算。
1.1.2 何为算法
为了理解什么是算法,先看一道有趣的智力题。
“烧水泡茶”有如下5道工序:①烧开水,②洗茶壶,③洗茶杯,④拿茶叶,⑤泡茶。
烧开水、洗茶壶、洗茶杯、拿茶叶是泡茶的前提。其中,烧开水需要15min,洗茶壶需要2min,洗茶杯需要1min,拿茶叶需要1min,泡茶需要1min。
下面是“烧水泡茶”的两种方法。
方法1的步骤如下。
第1步:烧水。
第2步:水烧开后,洗刷茶具,拿茶叶。
第3步:沏茶。
方法2的步骤如下。
第1步:烧水。
第2步:烧水过程中,洗刷茶具,拿茶叶。
第3步:水烧开后沏茶。
问题:比较这两种方法有何不同,并分析哪种方法更优。
上述两种方法都能最终实现“烧水泡茶”的功能,每种方法的3个步骤就是一种“算法”。算法是指在有限步骤内求解某一问题所使用的一组定义明确的规则。通俗点说,就是计算机解题的过程。在这个过程中,无论是形成解题思路还是编写程序,都是在实施某种算法。前者是推理实现的算法,后者是操作实现的算法。
1.2 计算机中的算法
众所周知,做任何事情都需要一定的步骤。计算机虽然功能强大,能够帮助人们解决很多问题,但是计算机在解决问题时,也需要遵循一定的步骤。在编写程序实现某个项目功能时,也需要遵循一定的算法。在本节的内容中,将一起探寻算法在计算机中的地位,探索算法在计算机中的基本应用知识。
1.2.1 认识计算机中的算法
计算机中的算法可分为如下两大类。
数值运算算法:求解数值。
非数值运算算法:事务管理领域。
假设存在如下运算:1×2×3×4×5,为了计算上述运算结果,最普通的做法是按照如下步骤进行计算。
第1步:先计算1乘以2,得到结果2。
第2步:将步骤1得到的乘积2乘以3,计算得到结果6。
第3步:将6再乘以4,计算得24。
第4步:将24再乘以5,计算得120。
最终计算结果是120,上述第1步到第4步的计算过程就是一个算法。如果想用编程的方式来解决上述运算,通常会使用如下算法来实现。
第1步:假设定义t
=1。
第2步:令i
=2。
第3步:把t
×i
的乘积仍然放在变量t
中,可表示为t
×i
→t
。
第4步:把i
的值加1,即i
+1→i
。
第5步:如果i
≤5,返回重新执行步骤3以及其后的步骤4和步骤5;否则,算法结束。
由此可见,上述算法方式就是数学中的“n
!”公式。既然有了公式,在具体编程的时候,只需要使用这个公式就可以解决上述运算问题。
再看下面的一个数学应用问题。
假设有80个学生,要求打印输出成绩在60分以上的学生。
在此用n
表示学生学号,用ni
表示第i
个学生的学号;用cheng表示学生成绩,用chengi
表示第i
个学生的成绩。根据题目要求,可以写出如下算法。
第1步:1→i
。
第2步:如果chengi
≥60,则输出ni
和chengi
,否则不输出。
第3步:i
+1→i
。
第4步:如果i
≤80,返回步骤2;否则,结束。
由此可见,算法在计算机中的地位十分重要。所以在面对一个项目应用时,一定不要立即编写程序,而是要仔细思考解决这个问题的算法是什么。想出算法之后,以这个算法为指导思想来编程。
1.2.2 为什么说算法是程序的灵魂
算法是计算机处理信息的基础,因为计算机程序本质上就是算法,告诉计算机确切的步骤来执行一个指定的任务,如计算职工的薪水或打印学生的成绩单。通常,当算法在处理信息时,数据会从输入设备读取,写入输出设备,也可能保存起来供以后使用。
著名计算机科学家沃思提出了下面的公式。
实际上,一个程序应当采用结构化程序设计方法进行程序设计,并且用某种计算机语言来表示。因此,可以用下面的公式表示。
上述公式中的4个方面是一种程序设计语言所应具备的知识。在这4个方面中,算法是灵魂,数据结构是加工对象,语言是工具,编程需要采用合适的方法。其中,算法是用来解决“做什么”和“怎么做”的问题。实际上程序中的操作语句就是算法的体现,所以说,不了解算法就谈不上程序设计。数据是操作对象,对操作的描述便是操作步骤,操作的目的是对数据进行加工处理以得到期望的结果。举个通俗点的例子,厨师做菜肴,需要有菜谱。菜谱上一般应包括:①配料(数据),②操作步骤(算法)。这样,面对同一原料可以加工出不同风味的菜肴。
1.3 计算机中表示算法的方法
在1.2.1节中演示的算法都是通过语言描述来体现的。其实除了语言描述之外,还可以通过其他方法来描述算法。在接下来的内容中,将简单介绍几种表示算法的方法。
1.3.1 用流程图表示算法
流程图的描述格式如图1-1所示。
图1-1 流程图标识说明
再次回到1.2.1节中的问题。
假设有80个学生,要求输出成绩在60分以上的学生。
针对上述问题,可以使用图1-2所示的算法流程图来表示。
图1-2 算法流程图
在日常流程设计应用中,通常使用如下3种流程图结构。
顺序结构。顺序结构如图1-3所示,其中A
和B
两个框是顺序执行的,即在执行完A
以后再执行B
的操作。顺序结构是一种基本结构。 - 选择结构。选择结构也称为分支结构,如图1-4所示。此结构中必含一个判断框,根据给定的条件是否成立来选择是执行A
框还是B
框。无论条件是否成立,只能执行A
框或B
框之一,也就是说,A
、B
两框只有一个,也必须有一个被执行。若两框中有一框为空,程序仍然按两个分支的方向运行。 - 循环结构。循环结构分为两种,一种是当型循环,另一种是直到型循环。当型循环先判断条件P
是否成立,成立才执行A
操作,如图1-5(a)所示。而直到型循环先执行A
操作,再判断条件P
是否成立,成立再执行A
操作,如图1-5(b)所示。
图1-3 顺序结构
图1-4 选择结构
图1-5 循环结构
上述3种基本结构有如下4个特点,这4个特点对于理解算法很有帮助。
(1)只有一个入口。
(2)只有一个出口。
(3)结构内的每一部分都有机会被执行到。
(4)结构内不存在“死循环”。
1.3.2 用N-S流程图表示算法
在1973年,美国学者提出了N-S流程图的概念,通过它可以表示计算机的算法。N-S流程图由一些特定意义的图形、流程线及简要的文字说明构成,能够比较清晰明确地表示程序的运行过程。人们在使用传统流程图的过程中,发现流程线不一定是必需的,所以设计了一种新的流程图,这种新的方式可以把整个程序写在一个大框图内,这个大框图由若干个小的基本框图构成,这种新的流程图简称N-S流程图。
遵循N-S流程图的特点,N-S流程图的顺序结构图1-6所示、选择结构如图1-7所示、循环结构如图1-8所示。
图1-6 N-S流程图的顺序结构
图1-7 N-S流程图的选择结构
图1-8 N-S流程图的循环结构
1.3.3 用计算机语言表示算法
因为算法可以解决计算机中的编程问题,是计算机程序的灵魂,所以可以使用计算机语言来表示算法。当用计算机语言表示算法时,必须严格遵循所用语言的语法规则。再次回到1.2.1节中的问题:1×2×3×4×5。如果用Python语言编程来解决这个问题,可以通过如下代码实现。
源码路径:daima\第1章\math.py
上述代码是根据1.2.1节中的语言描述算法编写的,因为是用Python语言编写的,所以需要严格遵循Python语言的语法,例如严格的程序缩进规则。
1.4 学习建议
在一些培训班的广告中,到处充斥着“一个月打造高级程序员”的口号,书店里也随处可见书名打着“入门捷径”旗号的书。有过学习经验和工作经验的人们往往深有体会,这些宣传不能全信,学习编程需要付出辛苦和汗水,需要付出相当多的时间和精力。结合作者的学习经验,现给出如下学习建议。
(1)学得要深入,基础要扎实。
基础的作用不必多说,基础的重要性在大学课堂上老师曾经讲过很多次,在此重点说明“深入”。职场不是学校,企业要求你能高效地完成项目功能,但是现实中的项目种类繁多,需要从根本上掌握算法技术的精髓,入门水平不会被开发公司所接受,他们需要的是高手。
(2)要有恒心,不断演练,举一反三。
学习编程的过程是枯燥的,要将学习算法作为自己的乐趣,只有做到持之以恒才能掌握到编程的精髓。另外,编程最注重实践,最害怕闭门造车。每一个语法,每一个知识点,都要反复用实例来演练,才能加深对知识的理解,并且要做到举一反三,只有这样才能对知识有深入的理解。
本文摘自《Python算法详解》
市面上许多与算法相关的图书会介绍大量的理论或者讲解表达算法的核心概念,但是这类书缺乏完整的程序设计范例,因而对于第一次接触算法的初学者来说,将算法运用于实际应用就成了一道跨不过的鸿沟。为了帮助更多人用比较轻松的方式了解各种算法和各种经典数学问题的求解方法,本书包括了枚举算法、分治算法、贪心算法、试探算法、迭代算法;线性表、队列和栈; 二叉树、霍夫曼树;图的遍历、图的连通性、寻求最短路径;查找算法;内部排序法、插入排序法、交换类排序法、选择排序法、归并排序法、基数排序法;经典的数据结构问题,如约瑟夫环、大整数运算、顺序表的处理、链表的基本操作、基于列表实现二叉树、实现AVL树、使用二维数组生成有向图;经典数学问题的解决,如利用递归算法获取斐波那契数列前n项的值、通过多个进程验证哥德巴赫猜想、百钱买百鸡、素数问题、埃及分数式等。
为了让读者学以致用,每讲一个算法,同时都会给出具体的实例和运行的效果图。同时使用Python实现算法,以期能将各种算法真正应用在学习者将来的程序设计中。因此,这是一本学习算法的入门书。
本文转载自异步社区。
原文链接:https://www.epubit.com/articleDetails?id=NNb6e4b6e6-a18f-4e6d-9cfe-4d2b7a3962f1
- 点赞
- 收藏
- 关注作者
评论(0)