分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow
也欢迎大家转载本篇文章。分享知识,造福人民,实现我们中华民族伟大复兴!
学过计算机的都知道,这本书可以说是全世界最权威的算法课程的大学课本了,基本上全世界的名牌大学用的教材都是它。这本书一共四位作者,Thomas H. Cormen,Charles E. Leiserson 和 Ronald L.Rivest 是来自 MIT 的教授,Clifford Stein 是MIT出来的博士,现在哥伦比亚大学做教授,四人姓氏的首字母联在一起即是此书的英文简称(CLRS 2e),其中第三作者 Ronald L. Rivest 是 RSA 算法的老大(算法名字里面的 R 即是指他)。
算法导论HTML版(点击打开网页) 算法导论习题部分答案(PDF)
现代计算机常用数据结构和算法(算法导论第一版中文版)(PDF)
Introduction to Algorithms, Second Edition(这是CHM格式的完美英文版,目录、附录、练习、插图都不缺)
算法导论 MIT 的视频课件:
该视频课件共24讲,由两位教授讲课,其中一位就是本书的作者 Charles E. Leiserson ,通过视频,让我们一起感受master的风采。由于每集有500M左右,不能提供本地下载,下面是麻省理工学院下载网址:(最好用多线程下载软件慢慢下^_^)
http://cypress.csail.mit.edu/lectix/
内容简介
| |
程序设计是计算机专业学生学习的主要方向,然而,本书作者认为,算法的分析与构建比编程本身更重要,只有很好地解决了算法问题,才可能编写出好的程序。为此,本书分三个部分讨论了计算与算法的问题。第一部分主要回顾了西方历史上各种社会范式的发展,使读者可以了解科学的发展、社会的进步与人类对各种思维范式的研究紧密相关。第二部分概述了用于实现算法的伪代码中的结构和组件、原子基本数据和操作、过程、函数、参数和递归等各种知识,还介绍了查找、排序、优化等算法,此外,关于面向对象范式、正确寻址、正确估算算法的资源成本等也在本部分有专门的章节介绍。第三部分的目标是帮助读者了解什么样的问题能用计算机解决,区分并发与并行的概念,同时进一步讨论了如何将算法与实际问题相关联,并给出了近50年来的各种编程范例。 本书适合于各类院校的学生用做计算机知识入门课本,也是喜爱编程的人们培养分析问题能力的最佳参考资料。 算法导论(原书第2版)-图书目录: 算法导论(原书第2版)-图书简介: |
图书目录
| |
第一部分 计算视角 第1章 技术、科学与文化的发展史 2 1.1 技术创新与人类进化 2 1.1.1 历史发展的模式 3 1.1.2 科学领域的范式变迁 3 1.1.3 范式变迁的特点 3 1.2 范式发展历史的概述 4 1.2.1 原始部族意识时代 4 1.2.2 字母表和抽象思维的萌芽 4 1.2.3 绝对抽象思维的时代 5 1.2.4 机械的媒体技术 6 1.2.5 “机械”思维的时代 7 1.2.6 电子媒体技术 7 1.3 最近几十年来技术发展回顾 8 1.3.1 社会形态变迁过程描述 8 1.3.2 正在形成中的社会形态的特征 9 1.3.3 新的社会形态的中心主题 10 1.4 正在形成中的社会形态 11 1.4.1 现象的算法概念 12 1.4.2 模拟和实验的方法 12 1.4.3 得到的启发 14 习题 16 第2章 算法模型 18 2.1 什么是算法 18 2.2 好算法的要素 21 2.2.1 精度 21 2.2.2 简单 21 2.2.3 抽象分级 22 2.3 算法与计算机 24 2.3.1 计算机做什么 24 2.3.2 计算机与二进制数据 24 2.3.3 计算机中的抽象分级 25 2.3.4 比较算法与计算机程序 27 2.3.5 比较数据与信息 27 2.4 算法组件 28 2.4.1 数据结构 28 2.4.2 数据操作指令 28 2.4.3 条件表达式 29 2.4.4 控制结构 29 2.4.5 模块 29 2.5 从计算视角看问题 30 2.5.1 用算法表达式构思行为 30 2.5.2 用过程构思展示行为的东西 30 2.5.3 用不同抽象等级构思算法 30 2.5.4 理解复杂度如何限制算法的有用性 31 2.5.5 撇开其他视角 32 小结 33 习题 34 第二部分 算法工具 第3章 基本数据与操作 38 3.1 算法语言 38 3.2 创建简单变量 39 3.2.1 变量标识符 40 3.3 运算符 40 3.3.1 赋值运算符 40 3.3.2 基本操作 41 3.3.3 输入/输出运算符 42 3.4 原子数据类型 44 3.4.1 数字型 44 3.4.2 字符 44 3.4.3 布尔型 45 3.4.4 指针型 45 3.5 复杂数据类型 45 3.5.1 字符串 45 3.5.2 其他复杂数据类型 46 3.6 变量声明和初始化 46 3.6.1 数据声明的位置 46 3.6.2 选择标识符名字 46 3.6.3 初始化变量 46 3.7 固定的数据 47 3.7.1 常量 47 3.7.2 文字值 47 3.8 一般规则 48 3.8.1 算法的一般结构 48 3.8.2 标识符格式 49 3.8.3 类型匹配 49 3.9 算法判定 50 3.9.1 基本判定 50 3.9.2 判定与数据类型 51 3.9.3 判定活动 51 3.9.4 复杂判定与布尔操作比较 54 3.9.5 嵌套的判定 56 小结 59 习题 59 第4章 过程抽象的方法 62 4.1 基本思想 62 4.2 根据什么模块化 63 4.3 对模块接口的需要 63 4.3.1 参数 64 4.3.2 参数的三种基本类型 64 4.4 模块的创建和使用 64 4.4.1 创建过程和函数 65 4.4.2 调用过程和函数 67 4.4.3 使用多个参数 68 4.5 参数表 71 4.6 数据作用域 71 4.6.1 作用域的三种有效范围 72 4.6.2 变量的作用域 72 4.6.3 常量作用域 72 4.7 参数的类型 73 4.7.1 输入参数 74 4.7.2 输出参数 75 4.7.3 输入/输出参数 78 4.8 较大的范例 80 4.9 过程抽象的重要性 83 4.9.1 编写算法 83 4.9.2 测试代码 84 4.9.3 维护代码 85 4.9.4 重用逻辑 85 4.9.5 在不同算法中重用编码 87 4.10 递归控制 87 4.10.1 递归的两种形式 88 4.10.2 跟踪递归模块的执行 89 4.10.3 用递归解决问题 90 4.10.4 使用堆栈来跟踪代码 91 4.10.5 递归的作用 94 小结 96 习题 97 第5章 数据抽象的方法 102 5.1 数据的意义 102 5.2 组织多个数据块 103 5.3 记录 103 5.3.1 创建新的记录数据类型 104 5.3.2 访问记录的数据域 105 5.4 类型与变量的区别 105 5.4.1 数据类型扩展了语言 105 5.4.2 数据类型的作用域 106 5.4.3 用户自定义数据类型的抽象能力 106 5.4.4 匿名数据类型 107 5.5 指针 107 5.6 动态数据结构 109 5.7 链表 110 5.7.1 链表的结构 110 5.7.2 使用指针来访问节点 111 5.7.3 使用指针来添加节点 115 5.7.4 使用指针来删除节点 115 5.7.5 导航链表 117 5.7.6 遍历链表 117 5.7.7 递归链表遍历 117 5.7.8 递归链表的查找 120 5.7.9 简化表达式的计算 120 5.7.10 建立链表 121 5.7.11 从链表中删除值 124 5.7.12 链表特性小结 125 5.8 链接数据的作用域 125 5.8.1 静态与动态变量 125 5.8.2 在链接数据的参数保护中的漏洞 128 5.9 二叉树 129 5.9.1 遍历二叉树 130 5.9.2 二叉查找树 132 5.9.3 中序遍历BST 132 5.9.4 前序和后序遍历 135 5.9.5 查找二叉查找树 136 5.9.6 添加节点到BST中 138 5.9.7 从BST中删除节点 138 5.10 图 139 5.11 迭代控制 140 5.12 迭代与递归 143 5.13 数组 144 5.13.1 数组与链表 146 5.13.2 遍历数组 146 5.13.3 查找数组 147 5.13.4 更有效的数组查找 147 5.14 常量的强大抽象能力 149 5.14.1 易修改性 149 5.14.2 可读性 150 5.15 创建新数据类型的强大抽象能力 150 5.15.1 混合使用原子类型和复杂类型 151 5.15.2 记录数组 151 5.15.3 记录的记录 154 5.15.4 数组的数组 155 小结 157 习题 158 第6章 构造算法的方法 162 6.1 遍历 162 6.1.1 遍历线性结构 162 6.1.2 遍历非线性结构 163 6.1.3 堆栈和队列 164 6.1.4 广度优先遍历 167 6.1.5 广度优先遍历的实现 169 6.2 查找 170 6.2.1 用遍历实现简单查找 170 6.2.2 关键字域 170 6.2.3 更有效的查找 171 6.3 排序 172 6.4 划分与求解 173 6.5 优化 176 6.5.1 贪心算法 176 6.5.2 动态编程 179 小结 181 习题 182 第7章 现实世界对象的建模方法 185 7.1 面向对象的范式 185 7.1.1 面向对象方法的优势 186 7.1.2 面向对象方法应具有的特征 186 7.2 实现良好的封装性 186 7.2.1 过程抽象和数据抽象的局限性 187 7.2.2 抽象数据类型的概念 187 7.2.3 使用类定义抽象数据类型 188 7.2.4 使用对象来创建抽象数据类型的实例 190 7.3 类的剖析 190 7.3.1 public部分 192 7.3.2 protected部分 192 7.3.3 类中数据的作用域 193 7.3.4 说明 194 7.3.5 声明和使用对象 194 7.4 类属参数和可重用性 195 7.5 跟踪对象行为的执行 197 7.6 复制和克隆操作 198 7.7 实现良好的可适应性 201 7.7.1 继承和扩展行为 201 7.7.2 重新定义继承的标识 202 7.7.3 修改public/protected状态 204 7.7.4 继承类型小结 204 7.7.5 解决二义性 205 7.8 实现多态性 205 7.9 任何事物都是对象 208 小结 213 习题 214 第8章 验证正确性的方法 218 8.1 Bug和调试 218 8.1.1 二义性 219 8.1.2 语法错误 219 8.1.3 语义错误 219 8.1.4 逻辑错误 221 8.2 证明算法的正确性 223 8.3 验证法 225 8.4 能做的最重要的事情 225 小结 228 习题 228 第9章 估算成本和复杂度的方法 232 9.1 性能度量 232 9.2 工作度量 234 9.3 所做工作的分析 235 9.4 实际输入与随机输入 236 9.5 增加复杂度 236 9.6 性能和数据结构 240 9.7 进一步增加复杂度 241 9.8 估算冒泡排序法的复杂度 243 9.9 合理算法和不合理算法 247 9.10 不合理算法的种类 250 小结 252 习题 252 第三部分 计算的局限性 第10章 并发与并行 256 10.1 概述:并发与并行 256 10.1.1 什么是并发 256 10.1.2 什么是并行 257 10.1.3 两者之间的混淆 257 10.2 并发 258 10.2.1 多道程序设计 258 10.2.2 多重处理 258 10.2.3 多任务 258 10.2.4 分布式系统 259 10.3 并发中的问题 259 10.3.1 保护 259 10.3.2 公平性 259 10.3.3 死锁 260 10.3.4 并发问题的总结 261 10.4 并行 261 10.5 并行的局限 263 10.5.1 处理器的固定数量 263 10.5.2 额外开销 264 10.5.3 依赖 264 10.5.4 优先顺序 268 小结 271 习题 271 第11章 问题复杂度的层次 274 11.1 问题复杂度 274 11.2 开放式问题和闭合式问题 275 11.3 简单问题和复杂问题 275 11.4 跨越界限的问题 276 11.5 NP完全问题 276 11.6 证明、预言和确定性 277 11.6.1 证明 278 11.6.2 预言 278 11.6.3 确定性与非确定性 279 11.7 NP完全问题和复杂问题 279 11.8 不可判定问题 279 11.8.1 不可判定问题的证明 281 小结 282 习题 283 第12章 计算与算法的历史 285 12.1 原始范式 285 12.2 抽象的出现 285 12.3 完全抽象的范式 286 12.4 机械装置的出现 286 12.5 机械论思想的范式 286 12.6 实时连接的出现 287 12.7 互联过程范式 287 12.8 未来趋势 288 |
序言/前言
| |
译 者 序 20世纪最重要的发明是计算机,从表面上看,21世纪计算机和网络的不断应用将完全改变人们的生活方式,但是我们是否想过:今天的基因工程、生物医学研究、太空探测、每日天气预报等,都与计算机科学有着密不可分的关系,计算机不仅从形式上改变了人们的生活,而且从思维的深处改变着人类了解世界、研究世界的模式。 这些说起来那么神奇,与普通人离得非常遥远,可是翻开本书,从第1章、第2章短短的字里行间,我们就会了解我们每一个人都能充分理解人类进程的发展,并且真实感受和参与了这场社会变革,而且随着社会的变革,我们自觉与不自觉地改变了自己的思维——因为时代的思维范式确定了我们的行为。 那么,我们这个时代的思维范式是什么?就是计算范式。它复杂吗?难以理解吗?不,一点也不,只要把思维的方式与真正的实现分离开来看,它不过是一种与菜谱、游戏规则相类似的一组操作指令表,透过建立这些指令表的思维,不仅可以理解计算机的工作原理,而且可以学会建立自己的指令表,学会指挥计算机工作的思维。其实我们每天都在执行很多指令序列,只是从没有用专业术语即程序来称呼这些指令序列,我们从没有认真考虑过它们应该属于计算范式的思维模式。 本书回顾了西方历史上各种社会范式的发展,以及伴随范式而出现的科技进步、社会变革,并展望了现有思维范式的未来前景。其次用一种伪代码语言带领读者开始新思维的建立,并列举了许多常见算法的实现,以及计算机能力的局限性。 本书是为所有正在用计算机和打算用计算机的人们编写的,它虽然是一本理论类的书籍,但它与实际操作只有一步之遥。读者只要掌握任何一门计算机语言,就可以将本书中的例题稍加改造而真正实现。同时,本书也是一本计算机科学的入门书籍,任何致力于培养计算机科学工程师的院校都可以选用本书作为教材。 本书的翻译是集体劳动的成果。翻译人员有:杨东 、章小莉、孙厚琴、汪永好、赵慧麟;此外,还得到了李正阳、王艳红、朱德芳、王玉琴、张宇、范永斌、徐日、周韩、宋燕红、曹驰、李珊、曹长宏等人的大力支持。 由于译者水平有限,难免有错译或不当之处,敬请读者批评指正。 前 言 概述 本书和它代表的入门课程是我们在Georgia计算机技术学院(Georgia Tech)进行计算机教育努力的结果,与此同时达到了两个目标: 1. 修正众所周知的计算机科学入门课程中存在的一些问题。 2. 满足各种需要计算机基础知识的学生的要求。 我们的努力已经被我们学校所在地区的人们广泛承认:使得仅在两年之内入学的新生人数从100人暴涨到1400人,现在该课程也被指定为大学教育中的核心课程。 因此,通过快速增长的入学人数,我们在所需的计算机入门教育新方法和班级管理技术方面获得了经验。顺着这条路,我们建立了跟踪学生的能力和学生对课程看法的过程,根据结果,我们更多地知道我们努力的效果比别的方式更好,这一追踪过程使我们能洞察新课程的开设将要冒多大的风险,也更相信获得的成果,事实上这是一个正面意义的成果。 本书读者和先行知识 本书的读者是各种学院和大学的广大学生,从我们过去5年的经验来看,所有教育和学习课程表上列有计算机科学、工程科学、自然科学、社会科学、数学、管理学、结构学为主课的学生都可成为本书的读者。我们仅缺乏对学习古典文学和健康科学的学生的教学经验,因为Georgia Tech不提供这些学科的教育课程。 学习本书知识不需要读者受过任何大学教育,但需要具有高中基础教育阶段的代数学基础和独立思维的能力。 本书使用方法说明 事实上,最近的10年清楚地显示计算机已经彻底地影响了科学、商业和通信。在这一点上,计算机与其他学科不同,计算机至少以两种方式影响着每个人。在工具类方面,计算机几乎正改变着人类所统治的每个领域。在概念方面,计算机正提供思维框架,这构成了实际上各个学科的尖端研究的基础。计算机无论是作为工具,还是它的思维方式都是当今新的社会范式的基础。这种新的范式正席卷整个现代社会。 我们坚信计算机学科的教育应该扩大它的视角,以便在社会提升计算这个新角色的地位。对于全世界来说,C++与Java之间和UNIX与Windows之间的不同,是一件小事。相反,对人类知识和理解力的历史来说,广泛地接受现象的算法模型是具有非常大的影响力的事情。在整个自然科学和行为科学中,艺术现在的形式是用算法术语表达的模型化现象,它生产了算法可以模拟测试和优化的这些模型。算法为理论和经验的学习提供了新的基本“游戏规则”基础。 我们坚信所有提供高质量教育的学院培养的学生应该接受算法思想的基本方法训练,也有经验表明,他们也应该将该课程添加到思维模式建立的训练中。本书中面向算法过程的建立不仅是计算机科学的主要内容,而且为广大的自学学生提供了“21世纪的基础知识”。计算机将导致人们生活现状的改变。未来受过良好教育的人们,需要知道计算机内部的思想和局限性。为此,我们的方法有三个主要目标:提供该领域的入门教育,提供该领域的概念内容和软件训练,以及为学生打好编程基础。 目标1:提供领域的入门教育 与其他学科课程不同,传统的计算机科学课程没有对学科的概念和智力基础的实质性概述,相反,总是一开始就让学生在没有任何基础的情况下“编写程序”。 与计算机相关的入门课程应该介绍些什么内容呢?一种可能是:入门课程应该给学生提供一个浏览计算机科学领域中各子学科的机会(例如在第四周必须了解操作系统)。我们不是沿用这样的老方法,因为我们的目的是使入门的学生理解计算机的主要思想,不是当前计算机科学各个组成部分的内容。我们发现,对计算机科学不为主课的学生来说,“浏览”并不能使他们建立起基本概念(而且可能更糊涂)。 我们采取的方法是认为计算机科学领域中核心的概念是算法,因此,我们把算法作为学习的主体。这种做法呼唤对基本思路的介绍,包括给一年级新生量身定做的基本算法结构和一定的理论基础。 目标2:提供概念的介绍和软件的训练 计算机的巨大冲击使得全体大学生都必须掌握计算机的基本使用技能。在许多大学,已经出现对计算机使用和标准软件应用相关的基本入门学习的需要。通常,这一需求导致了将计算机作为工具的非编程课程的出现(例如,教育学生使用字处理软件和电子表格软件等)。 我们坚决同意入门类计算机课程应该包含这些内容,但我们不同意这些内容就是全部。以我们的观点,“应用程序的使用”着重的是技术问题,因此它可以放在实践类课程中完成,但它缺乏主要内容,因而对大学水平的课程来说,将它作为基础课程是否合适是值得深思的问题。对我们来说,大学中学习怎样使用电子表格获得的学分无疑等价于电子工程系的学生学习焊接工艺或机械工程技生学习焊接工艺类课程获得的学分。 因此,我们开设的“计算机入门”课程具有交叉类学科的特点,当讲课与作业的主要内容是使用各种标准应用软件时,学校教与学的重要内容是从概念上构建和分析算法。本书提供教与学的训练,我们坚信它与不追究实现细节的各类大学课程相似。另一方面,实验自然有它的不同,要以任务研究和当地的计算机资源为基础。我们提供的实验训练要求以通用PC和基于PC的软件为操作环境,且具备经由网络实现对UNIX资源的访问。在原理上,它能在局域网环境中得以实现,书中实验训练内容由五大模块组件构成: ● 通信工具和设备。介绍电子邮件和新闻组、文本和图形编辑、桌面出版系统和html主页的创建。时间为4周。 ● 数据处理工具和设备。介绍数据库、电子表格和解方程式软件。时间为4周。 ● 问题求解。主要介绍解决特定学科问题的工具和设备的使用。时间为3周。 ● 体验编程。第二阶段可称为“编程入门”的序言,它介绍Java的基本知识,包括构建组件和快速产生原型,用模仿和娱乐的方法进行教学。时间为3周。 ● 实验训练估算。“告诉我你可以干什么”,基于实验的最后测验,安排在课程的最后阶段。 有关实验训练的更多信息和支持材料可以从面向用户的出版网站(参见补充资料)获得。 目标3:为编程打基础 教授传统编程入门课程的老师们的抱怨出奇地相似 :在这类课程中,学生不理睬设计和实现的训练,怀疑文档的价值,不追求程序设计对问题的抽象,对答案“不求质量”。所有问题在于学生完全不理睬教师关于“编写”好程序应该做什么的教诲,这些及类似的教与学的问题无所不在。以我们的观点看,所有这些问题是关于编程的传统入门方法自然导致的结果,(a)因为它们使设计和实现问题模糊不清;(b)过早地让学生面对程序的实现任务;(c)课堂上一般过于强调特定语言环境中的结构和技术的实现。 我们坚信让学生在狭隘的特定语言环境(因此难以掌握有效的抽象)中积累经验是传统方法的目标,因为这种方法同时将学生放在编程环境中,要求他们必须解决好算法执行需求问题(因此,暗含着强调学生对实现而不是设计更关心),其结果预示着:当学生“在与编译器奋战至夜里2点的时候,他们很快就失去了对设计与抽象的全部感觉,所有的一切都被“在这里放个分号,在那里放个逗号,看工作吗”的调试过程所取代。我们坚信要克服这种现象,需要把实现与调试和设计与抽象分开来学习。经验告诉我们:如果没有将这两方面的问题区别开来,学生将过分专注于后者,其结果是绝对难以让他们关注前者,分散了他们学习前者的精力。 因此,我们尽力做到在简单的环境(写伪代码和画图方式)中学习抽象和设计的基本问题,在简单环境中,由于学习中不接近编译器,因此学员自身的能力决定了最后自己的水平。关于这一点,清晰地表明设计和实现比语言编译和算法的精确度更重要。一旦学生打下了设计和实现的基础,我们才加上必须满足计算机需求的学习。我们坚决主张在第一阶段课程(计算机入门)中,学生应该将精力集中在掌握逻辑抽象和设计的学习,以便他们进入第二阶段学习(编程入门)时了解他们正在努力干什么。第一阶段是基本方法概念和技术介绍,第二阶段的高级课程主要是学习有效设计、实现、测试和调试技巧与策略。简而言之,我们认为给学生打下编程基础的秘密是直接让他们获得这些准备。我们相信,与之相反的做法(特别是当在入门课程学习C++和Java这样的复杂语言时)都将是不明智的,只会取得不好的效果。 课程内容 本书共分三大部分,它们是: 第一部分:计算视角 这一部分的内容不含技术。第1章介绍了西方历史和科学中的计算问题,其目的是让学生了解计算的视角,以及人类关于知识和我们生存的世界之间的关系。在这一章中要触发学生对大范围而不仅是日常技术相关问题的好奇心。这一目标支持刺激学生进行反思,关注“大问题”的传统教学目标。紧接着的第2章高度概括了什么是算法、算法的组成和与算法术语相关的问题。 内容选择 后续各章的学习可以不需要第1章做基础,因此,第1章可以不讲或作为选修材料。但是,从我们的经验来看,大三或大四的学生通常反映这一章的内容(对应的第一堂课)最能刺激他们整个大学期间的学习。第2章内容是后续课程的基础,因此为必修课。 第二部分:算法实现工具 这些章占据本书的大部分篇幅。在第二部分,快速全面概括了算法结构和相关的伪代码组成。第3章介绍基本数据和操作。第4章介绍过程抽象,包括过程、函数、参数和递归。第5章介绍整个的数据结构,包括记录、数组、链表、树和图。第6章介绍常用算法,如查找、遍历、排序和优化算法。第7章介绍与结构相关的面向对象范式。第8章解决改错和验证问题。第9章让学生理解和估算算法成本和复杂度的方法,并掌握对它们的估算,正确区别合理的和不合理的性能。掌握这些章节的知识之后,实际上学生已经准备好学习任何一种编程语言,已经完全掌握了软件工程和计算机科学理论的基础知识。 内容选择 第3~6章为必修课,一章一章知识相互衔接。第7章介绍面向对象范式,对那些还不打算学习这种范式的人来说,可以跳过本章不学。对于学习者来说,第7章可以直接在第6章之后学,也可以在第9章之后学。我们试验过在课程的不同阶段讲授它,目前是在第6章之后讲授它。经验表明过早学习这一章(如在第5章之后)效果不佳。但是如果放在第9章与第10章之间,则是可行的。将这部分内容移至第9章之后的主要优点是这种安排为排序算法的练习提供更多的解决方案,因此更利于学生消化所学内容。 第三部分:计算的局限性 这一部分的目的是帮助学生理解计算机可以做什么和不可以做什么。第10章讲述并发和并行,告诉学生如何通过并行突破可能的性能限制的逻辑关系。第11章扩展了第9章中的算法到问题概述,向学生介绍了确定的、不确定的和NP完全问题的概念,也更进一步从实践和理论的角度概括了计算机能解决的各种问题。最后,第12章重回到第1章历史发展的主题,同样给出了各种西方历史范式的发展和近50年来的各种编程范式的发展。 内容选择 对寻找方法让学生正确理解计算机能做什么和不能做什么的课程来说,这一部分是必修内容。对于只打算让学生学习算法和相关结构编程基础的课程来说,这一部分可以选修。很显然,我们的愿望是让学生从一开始就打下良好的基础,因此,这一内容作为必修课。同时,我们认识到有人可能不赞同这种课程目标和做这样的优先处理,另一些人可以希望用一整学期来学习前两部分。 给老师的话 本书在下面几个方面与一般的计算机科学入门课程用书不同: ● 对入门课程来说,它认为应该把现代编程语言的教学转变成“更多”理论的教学。 当20世纪60年代中期第一门关于编程的入门课程出现时,这一课程是合理的必修课。那时,今天我们了解的计算机科学尚不存在,计算机就意味着编程,编程语言本身很简单,这一课程主要是教授仅有的几个问题(如赋值、数据操作、原子数据类型、数组、if-then-else语句、带参数的过程、文件操作和简单的文本I/O格式),简言之,我们能够教全部吗?大多数时候,我们肯定能。 在最近的30年中,关于计算机,几乎所有的内容都发生了变化,现在当我们考察编程入门训练时,我们不仅能找到原始课程中的八大术语,而且还存在有更多的内容。现在,课程内容有指针、链表、树、递归、结构设计、交互式调试器、交互式程序、人-机接口、屏幕图形、大程序、软件工程、复杂算法、多种语言、应用软件的应用,还有面向对象的设计和便携式程序,并且按照三个因素在增长。更进一步看,我们发现上述所提的内容每一项都比以前更复杂,实际上,教和学受到的挑战被大量因素影响,而且难度越来越大。 我们不是轻易决定要让学生上这门课,因为可以看到高年级的学生已经养成了很不好的习惯,他们对设计没有良好的认识,只追求仅有的软件开发的感觉。错,既不在学生,也不出自教师,而是因为基于语句的设计自身的问题。就基本入门教材而言,它含的内容太多了,很难在很短的时间内教完。其结果是教得越少,学得就越有效。学生学得很仔细,他们能用好指针,能遍历数据结构,但是他们从来没有以某种方式“获得”我们要他们“得到”的知识——抽象、设计、实现和估算的综合能力。我们注意到我们从来没有将这些内容放在一起教,学生也从来没有将它们放在一起学和用。大部分时间我们没有这么讲,是因为课程中没有足够的时间来做这件事。 ● 为了获得时间,在真正的编程语言和真正的编程学习过程中,我们选择跳过许多烦人的内容细节不讲。 现代编程语言有几个烦人的方面。其中最烦人的是它们的语言和语义非常精密,使得实际用它们进行编程完成某个练习时往往受挫,特别是对初学者来说。实际上,为了将学生从成功编译和执行程序所需的要求中分离出来,专心我们要他们掌握的原理的学习,我们用伪代码语言——不需要任何实用处理器的编译或执行支持——来完成这种分离。事实上,学生不再花难以计数的时间来与编译器较劲,从而节省了大量的时间和精力。 另外,由于仅将自己的精力集中在基本结构(或多或少),不理睬各种与实际语言的交互,也使我们节省了大量的时间。例如,不管复杂的I/O命令,只用简单的输入和输出语句,至少可以节省一周半的时间。只用单个循环而不是三或四重循环可以节省一周时间。只用单一分支语句可以节省半周时间。实际上,当我们努力让学生专心于算法的理解和学习时,我们就把大量非基础语言细节的学习限制为最简单的语法学习,省去了编译和执行不通过的烦恼,这意味着我们可以集中精力学习重要原理和它们的应用。我们知道学生会因一些难题而分心,所以我们去掉了大部分难题而没有牺牲抽象的功能。 ● 给学生“更大的想像空间”。 计算机教育几乎与每个人有关,这一事实意味着我们不再在遇到高级决策课题时才开始重视主题的讲解,这样做意味着非主修计算机科学课程的学生不用面对语言,减少了语法和编译的困惑,这也意味着我们可以在低年级学生学习中实现计算机科学中关键原理的讲解。因为在入门阶段我们主要强调基本软件工程原理(而不是关心它们的实现),学生不会养成后面必须消除的坏习惯,因为我们早早地介绍的是绝对的原理和复杂理论的应用,学生从没有机会“害怕”理论,使他们将算法的完成看成是自然的和一般的问题。 强调使用强大的软件应用程序进行实践与面向算法的学与做的训练的组合,意味着学生通过抽象的算法原理和广泛应用于这些复杂应用所需的模块设计学会了使用这些原理。因为学生在入门课程中彻底从概念上掌握了复杂的算法结构,当他们进入后续的“编程入门”课程时,知道了他们正努力做的事情是什么,以及为什么这样做。因此他们将以更加稳健的步伐在编程课上取得进步,比以前在编程方面可能取得更大、更多的进步。 ● 在面向结构与面向对象编程之间架起了桥梁。 作为许多编程解决方案中的一种可选方法的面向对象编程(OOP)范式是为了替代费时费力的结构化程序设计范式而出现的。OOP范式有更多的语言特性,它暗示着在算法设计上存在根本的不同。同时,世界上大多数东西是,并将继续是嵌入在结构化范式中,因此,我们面对的尴尬是继续使用众所周知的、有一定效果的和有用的结构化范式,还是转而使用初现的OOP范式,不再顾及大多数学生和这些未来的员工在实际使用它们时它们存在的缺点。 当然,我们坚信两者都不可取。一方面我们不能不理睬向oop的发展,或通过Java向硬件独立的OOP的发展。我们坚信Java语言,与www相互协作使用,不久的将来将戏剧性地改变很多东西。同时,我们对面向结构方法正在走下坡路这一论点表示怀疑,特别是因为它可以当做OOP语言的基础来学习,也因为结构化方法确实在许多学生和雇员中拥有自己的地位。 现在,我们选择让学生既学习面向对象范式,又学习OOP范式,因此,关于过程和数据抽象、算法方法的章节打下了面向结构范式的基础,随后通过仅需的结构知识的学习,实现OOP方法基础入门,从而使学生具备使用Pascal,Ada,C和FORTRAN的能力。他们也肯定有“操作能力”,能快速地在OOP的Java和C++世界中游刃有余。对那些认为我们应该完全向oop方向转换的人们,我们说“是的,但不完全是”。我们期望本书的未来版本会更多地在oop方向上进行问题讨论,但我们坚信,忽视结构化范式的时代还不会到来,这是软件世界中的转变时代,这一版图书也在这方面有意做了努力。 参考资料 本书的参考资料如下: 1. 出版公司的网站,www.awl.com/cseng/titles/0-201-31451-7/,在那里可以找到早期关于“方法解释”方面的应用程序的实验材料,找到与本书相关的参考资料。 2. 教师手册。含有我们从实践中总结出来的特殊教学方法,以及例题的答案和建议的估算策略。 3. 作者的研究。包括各种教与学效果的跟踪结果和优化策略,更有在整个课程学习过程中通过email与我们合作的合作伙伴的工作成果。 致谢 仅仅五年中,在 Georgia Tech大学我们尝试了一种新方法来完成计算机教育的入门课程,并使它成为了大学的核心课程。从五年前的角度来看,任何一种改变看上去都不讨人喜欢(如果不是不可能)。我的朋友和同学Peter Freeman,Richard LeBlanc和Kurt Eiselt大力支持和鼓励我走过了改变现存状况的烦人过程。实际上,他们是使改变得以实现的人。另外,Richard LeBlanc也积极参与了课程和内容的修正。 这个项目的核心思想是在众多人的帮助下完成的,许多本科学生充当了教学助手,这些助手在课程中为了实现每学期几百名学生从思想到工作过程的平稳过渡起了关键作用。他们大多工作很长时间、获得很少报酬,目的是使所在的学校更加完美。这些助手多得令人难以记住他们的名字,但要特别提到的有(按字母顺序)John Brewster,Mark Canup,Charlie Carson,Becky Carvin,Dameon Kindall,Brian McNamera,Jon Preston,Roy Rodenstein,Enda Sullivan和Brian Toothman,他们都对课程或书本的多方面做出了贡献,解决了其中的不少问题,并初步试用了本书的内容。另外,Jason Bennett,Stu Bernstein,Mike Brogdon,Theresa Browne,Paul Griswold,Jim Hudson,Steven Knickerbocker,Danny Lentz,Geoff Menegay,Kristen Schaffer,Emily Stretch和Adrian Yang也做出了重要的贡献,使得我认识到入门课程对毕业学生与教员的有价值的改革。就本人而言,我和学生们热情和高兴地共同工作着,我以极大的热情向他们推荐本书。 我的工作是以广泛流行的David Harel的工作为基础的。我们认为他的书“Algorithmics: The Spirit of Computing”清晰地介绍了计算机科学的基本思想,原书的目的是给“有基础的人们和计算机专家”看的,我们努力采用他的训练方式对现代大学生进行培训,不管我们是成功还是失败,正是Harel的工作激发了我们进一步努力,我们从他那里学到了他推荐给我们的一些我们不知道的方法,从而为我们打开了一个激动人心的新世界。 将一门课程和它相应的实验写成一本书是一件复杂和耗费经历的工作。当我在Georgia Tech验证本书的初稿时,它获得了较高的评价。在准备本书的过程中,我从下列列出的人员那里得到大量无价的帮助,他们对原稿进行了评价和批评指正:耶鲁大学的Roger M. Smith,Potsdam SUNY的Charles Marshall,Southern Maine大学的Stephen Fenner,Austin Texas大学的R. Philip Bording,Stony Brook SUNY的Peter B. Henderson,Idaho大学的John Dickinson,Central Florida大学的Niel da Vitoria Lobo,Stonehill大学的Ralph Bravaco,North Carolina A&T州立大学的Ray Hawkins。由于他们的努力,本书的内容发生了巨大的变化。我从他们几个坦率的有兴趣的建议和与我合作的工作中受益匪浅。 Addison Wesley Longman的许多人也在本书的写作过程中给我提供了有益的帮助,帮我完成了工作,其中Dorothy Moore,Susan Hartman,Amy Willcutt,Julie Dunn和Tom ZiolKowski最值得一提。另外,编辑Stephanie Magean和Bobbie Lewis也帮我克服了不少文字上的问题。最后在我与AWL联系之前,我幸运地从Debbie Berridge处取得有价值的支持和意见。 Russell Shackelford Atlanta, Georgia |
|
门市地址: 北京市海淀区万寿路南口173#信箱(乘68、451、809路公共汽车莲宝路口北下车即到) | |
电子工业出版社新址: 北京市万寿路南口金家村288号 华信大厦 服务电话: 010-88258888 88254114 |