华信教育资源网
算法设计与问题求解——编程实践
丛   书   名: 北京市高等教育精品教材立项项目  高等学校规划教材
作   译   者:李清勇 出 版 日 期:2013-06-01
出   版   社:电子工业出版社 维   护   人:袁玺 
书   代   号:G0203270 I S B N:9787121203275

图书简介:

本书是北京市精品教材立项项目,是大学生创新实践课程“算法设计与实践”课程教材。本书以问题求解为目标,以高级程序设计语言C/C++为工具,讨论怎样综合运用算法(包括数据结构)知识去分析问题和解决问题。问题驱动,高级语言程序设计、数据结构以及算法设计与分析知识交叉融合是本书的特点。配套理论教学的电子课件;实践教学用“在线程序评测系统”。包括问题求解与算法分析概述、基本数据结构、高级数据结构、枚举算法、递归与分治、 动态规划、贪心算法、搜索算法、图算法、算法分析的实用公式、在线程序评测系统简介等。
定价 35.0
您的专属联系人更多
配套资源 图书内容 样章/电子教材 图书评价
  • 配 套 资 源
    图书特别说明:

    本书资源

    本书暂无资源

    会员上传本书资源

  • 图 书 内 容

    内容简介

    本书是北京市精品教材立项项目,是大学生创新实践课程“算法设计与实践”课程教材。本书以问题求解为目标,以高级程序设计语言C/C++为工具,讨论怎样综合运用算法(包括数据结构)知识去分析问题和解决问题。问题驱动,高级语言程序设计、数据结构以及算法设计与分析知识交叉融合是本书的特点。配套理论教学的电子课件;实践教学用“在线程序评测系统”。包括问题求解与算法分析概述、基本数据结构、高级数据结构、枚举算法、递归与分治、 动态规划、贪心算法、搜索算法、图算法、算法分析的实用公式、在线程序评测系统简介等。

    图书详情

    ISBN:9787121203275
    开 本:16开
    页 数:248
    字 数:397

    本书目录

    第1章  计算机问题求解概述
    1.1  问题与问题实例
    1.2  计算机问题求解周期
    1.3  算法与程序
    1.4  算法复杂性分析
    1.4.1  空间复杂性
    1.4.2  时间复杂性
    1.4.2.1  时间复杂性的表示
    1.4.2.2  渐近时间复杂性及其阶
    1.4.2.3  时间复杂性渐近阶的意义
    1.4.2.4  算法时间复杂性分析
    习题1
    第2章  程序设计语言与数据结构
    2.1  程序设计语言的“盲点”
    2.1.1  long不够长
    2.1.1.1  数据类型的值域
    2.1.1.2  大整数相加算法
    2.1.2  double不够准
    2.1.2.1  浮点数的存储格式
    2.1.2.2  浮点数的有效数字
    2.1.2.3  高精度浮点数处理实例
    2.1.3  递归不够快
    2.2  基本数据结构
    2.2.1  线性表
    2.2.1.1  线性表的顺序存储结构
    2.2.1.2  线性表的链式存储结构
    2.2.2  栈和队列
    2.2.2.1  栈
    2.2.2.2  队列
    2.2.3  树和二叉树
    2.2.3.1  树
    2.2.3.2  二叉树
    2.2.4  优先队列和堆
    2.2.4.1  优先队列
    2.2.4.2  二叉堆
    2.2.5  图
    2.2.5.1  邻接矩阵
    2.2.5.2  邻接表
    2.3  标准模板库
    2.3.1  模板的基本概念
    2.3.2  标准模板库概述
    2.3.2.1  算法
    2.3.2.2  容器
    2.3.2.3  迭代器
    2.3.3  标准模板库应用
    2.3.3.1  向量(vector)
    2.3.3.2  集合和多重集合(set和multiset)
    2.3.3.3  映射和多重映射(map 和multimap)
    2.3.3.4  堆(heap)
    2.3.3.5  排序算法
    习题2
    第3章  枚举算法
    3.1  枚举的基本思想
    3.2  模糊数字
    3.3  m钱买n鸡
    3.4  真假银币
    习题3
    第4章  递归与分治
    4.1  递归程序
    4.2  分治策略的基本原理
    4.3  合并排序
    4.4  逆序对问题
    4.5  快速排序
    4.6  最接近点对问题
    4.7  指数运算
    4.8  二分查找
    习题4
    第5章  动态规划
    5.1  动态规划的基本思想
    5.1.1  动态规划的基本要素
    5.1.2  动态规划的求解步骤
    5.2  矩阵连乘
    5.3  最优二叉搜索树
    5.4  多段图最短路径
    5.5  最长公共子序列
    5.6  01背包问题
    5.7  最大上升子序列
    习题5
    第6章  贪心算法
    6.1  贪心算法的基本要素
    6.2  活动安排问题
    6.3  小数背包问题
    6.4  最优前缀码
    6.5  单源最短路径
    6.6  最小生成树
    6.6.1  Prim算法
    6.6.2  Kruskal算法
    6.7  贪心算法与动态规划、 分治算法的比较
    习题6
    第7章  搜索技术
    7.1  问题的状态空间表示
    7.2  深度优先搜索
    7.3  广度优先搜索
    7.4  回溯算法
    7.4.1  回溯算法的基本原理和框架程序
    7.4.2  装载问题的回溯算法
    7.4.3  圆排列问题
    7.5  分支限界
    7.5.1  分支限界法的基本原理
    7.5.2  装载问题的分支限界法
    7.6  启发式搜索
    7.6.1  启发式搜索基本原理
    7.6.2  装载问题的启发式搜索
    习题7
    附录A  复杂性分析的数学基础
    附录B  常用C语言和STL函数
    附录C  程序设计竞赛和OnlineJudge介绍
    参考文献
    展开

    前     言

    2006年3月, 美国卡内基-梅隆大学计算机科学系主任周以真(Jeannette M. Wing)教授在美国计算机权威期刊《Communications of the ACM》杂志上首先提出了计算思维(Computational Thinking)的概念。周教授认为: 计算思维是运用计算机科学的基础概念进行问题求解、 系统设计、 以及人类行为理解等涵盖计算机科学之广度的一系列思维活动。计算思维是每个人的基本技能, 不仅仅属于计算机科学家。我们应当使每个学生在培养解析能力时不仅掌握阅读、 写作和算术(Reading, wRiting and aRithmetic, 3R), 还要学会计算思维。正如印刷出版促进了3R的普及, 计算和计算机也以类似的正反馈促进了计算思维的传播, 计算机逐渐成为了当今问题求解的最重要工具。
    1.计算机与问题求解
    在20世纪40年代, 为了求解军事领域复杂的炮弹弹道计算问题, 科学家发明了第一台电子计算机“埃尼阿克”(Electronic Numerical Integrator And Computer, ENIAC)。随着计算机计算能力的增强, 计算机被广泛应用到了社会生活的各个领域。大到宇宙探测、 基因图谱绘制, 小到日常工作、 生活娱乐, 无不需要计算机的支持。
    作为“问题求解的一个有力工具”, 计算机尽管没有思维, 只能机械地执行指令, 但它运算速度快、 存储容量大、 计算精度高。如果能够设计有效的算法和程序, 充分利用这些优点, 计算机就能成为问题求解的一个利器。
    运算速度快是计算机最重要的特点之一。很多问题尽管比较复杂, 但仍然存在求解的方法, 只是这些方法往往计算量比较大, 计算过程较为繁琐, 人们难以在可以接受的时间内手工求解。
    【例】 用1, 2, 3, 4, 5, 6, 7, 8, 9九个数字拼成一个九位数, 每个数字使用一次且仅用一次, 要求得到的九位数的前三位、 中间三位和最后三位构成的三位数的比值为123。例如192384576就是一个符合该要求的数, 因为192384576=123。
    对于这样的问题, 很容易想到的一个求解方案是: 列举所有可能的九位数123456789, …, 987654321, 并逐个验证是否符合比值要求。理论上, 这是一个可行的办法, 可是几乎没有人愿意这样做。因为这样的九位数总共有9!=362880个, 即使每秒验证一个数(对于人工验证, 这已经是很快的速度了!), 也需要100多个小时。
    但是, 计算机实现同样的“笨方法”效果就大不一样。考虑用一个数组d保存九位数的各位数字, x, y, z分别代表前三位数、 中间三位数和最后三位数, 用STL中的函数next_permutation计算九个数字的下一个排列。当某个排列(即一个九位数)满足比例要求x y z=123时, 则输出该九位数。下面是解决此问题的C++代码, 在普通的PC机上运行该程序, 需要的时间还不到0.1秒。    void NineNumber() {
        int x , y , z; 
        int d[9]= {1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9}; 
        do{
            x=d [0] * 100+d [1] * 10+d [2]; 
            y=d [3] * 100+d [4] * 10+d [5]; 
            z=d [6] * 100+d [7] * 10+d [8]; 
            if(y == x * 2 && z == x * 3)
                cout << x << y << z << endl ; 
        } while (next_permutation(d , d+9));  // STL中的函数, 得到下一个排列
    }
    存储容量大是计算机的另一个重要特点。人们很容易记住10以内的两个数的乘积, 也就是小学数学中的“九九乘法表”。但如果要求人们记住100以内的任意两个数的乘积, 普通人可能会觉得“记忆”不够。但对于计算机来说, 这真是“小菜一碟”, 一个100×100的二维数组就可以把“百百乘法表”保存下来。
    人们常说的内存、 硬盘、 光盘、 U盘等都是存储器, 可以通俗地理解为计算机的记忆部件。容量的基本单位是字节(Byte), 记为B。其他单位有KB(1KB=1024B)、 MB(1MB=1024KB)、 GB(1GB=1024MB)等。容量越大, 可以存储的数据就越多, 其“记忆力”就越强。“百百乘法表”如果用一个100×100的二维int型整数(假设一个int型整数占2字节)数组保存, 它仅仅需要占用20 000字节(少于20KB)的空间。相比现在计算机动辄数GB的内存容量来说, “百百乘法表”的存储开销微不足道。
    需要特别指出的是, 运算速度快、 存储容量大仅仅是计算机硬件系统的两个突出特点。在实际问题求解过程中, 只有硬件平台还远远不够, 人们需要针对问题设计不同的算法, 并把算法转化为计算机可以运行的程序。
    2.计算机问题求解的知识体系
    计算机问题求解的本质是把特定领域中特定问题的求解过程转换为计算机可以执行的程序。在这个转换过程中, 除了必要的专业知识外, 问题求解者还需要掌握计算机算法设计方面的知识, 主要包括: 高级程序设计语言、 数据结构和算法。这些知识构成了计算机问题求解的核心知识体系。
    在计算机教学体系中, 高级程序设计语言、 数据结构、 算法是相互承接的课程系列。从计算机问题求解的角度看, 这三门课程的知识相互交叉、 相互支撑。高级程序设计语言和数据结构是算法设计的基础, 高效的算法和数据结构需要用某种高级程序设计语言去实现; 一个好程序不仅需要“编程小技巧”, 更需要合理的数据结构和高效的算法。
    程序设计语言是问题求解的基本工具。随着计算机技术的发展, 程序设计语言经历了一个从低级程序设计语言到高级程序设计语言的发展历程。机器语言和汇编语言等面向特定的体系结构和指令系统, 在计算机发展的早期应用较多。随着形式语言理论、 编译技术的发展, 与目标机器无关的高级程序设计语言(如C/C++, Java等)逐渐成为程序设计的主流。本书约定的程序设计语言是C/C++。需要注意的是, 程序设计语言并不等于程序设计, 程序设计的目的是表达程序设计者的思想, 按照计算机所能理解的方式描述需要让计算机完成的工作, 而程序设计语言只是表达这种思想的工具。程序设计的关键之处在于明确数据在计算机中的表达形式, 以及确定如何将输入转化为输出的一系列计算步骤, 而这些都需要数据结构和算法理论的指导。
    数据结构是问题求解的基础要素。数据是信息的载体, 无论是待求解问题的输入/输出, 还是问题求解过程中产生的中间量; 无论是简单的量, 比如单个数值, 还是复杂的对象, 它们在计算机中都是以数据的形式存储。在问题求解时, 为满足数据存储的结构化要求并提高程序执行效率, 人们首先面临的问题是怎样合理地组织、 存储和加工这些数据。常用的数据结构有线性表、 栈、 队列、 树、 二叉树、 图、 哈希表(散列表)等。数据结构的设计和应用不是一个教条化的生搬硬套过程, 同一个问题也许可以运用不同的数据结构求解, 而且它们求解的效率往往不尽相同。另外, 有些问题可能没有现成的数据结构直接套用, 需要人们综合运用基本数据结构组合成新的数据结构。无论是已有数据结构的选择还是新数据结构的设计, 人们都需要应用算法设计与分析方面的知识。
    算法设计是问题求解的关键要素。简单地说, 算法可以理解为把将问题输入转化为问题答案的一系列计算步骤。算法必须满足正确性与复杂性要求。首先, 算法执行结果必须正确, 它能正确无误地把每一个问题实例的正确答案求解出来。其次, 算法的复杂度要适中。计算机系统的资源(包括运行时间和存储空间)是有限的, 因此算法必须在有限的资源条件下正确地求解问题。同样的问题, 某些算法执行结果可能不正确, 某些算法执行结果正确无误。即使执行结果都正确的不同算法, 它们的执行效率可能也不尽相同, 如有些算法需要几个小时, 甚至几天, 有些算法却仅仅需要几秒钟或几分钟。算法设计是一个灵活的、 创造性的过程, 甚至可以认为是一个艺术创造过程。有些算法是现实生活中人们解决问题时所用办法的升华和抽象; 有些算法是数学理论和数学模型的体现和具体化。人们需要掌握经典的算法思想及其应用技巧, 也要学会怎样针对特定问题设计和创造新算法。
    3.本书的内容和结构
    本书是一本讲述怎样综合运用算法设计理论和技术进行问题求解的实践教材, 主要讲述算法设计原理和方法, 对运用算法求解问题时涉及的C/C++程序设计细节, 尤其是影响算法准确性和复杂性的编程要点和技巧也进行了详细阐述。数据结构往往是算法设计和实现的基础, 特别是一些高级数据结构, 其本身就体现了很强的算法思维, 因此本书不仅仅单独设立一章讲述数据结构, 在讨论具体算法时也会交叉讨论相应的数据结构知识。本书包括7章, 组织如下: 
    第1章介绍问题求解和算法的基本概念, 然后着重阐述了算法复杂度分析的基本理论和方法。
    第2章介绍程序设计和数据结构相关内容, 程序设计和数据结构是算法设计的重要支撑, 本章重点介绍了程序设计的三个盲点, 以及常用的基本数据结构及其用法。
    第3章介绍枚举算法。“大道至简”, 枚举算法是一种最朴素最简单的算法思想, 但在具有卓越运算速度的计算机系统中, 它却是常常被忽视的问题求解利器。本章重点阐述了怎样直接和间接运用枚举算法求解问题。
    第4章介绍递归和分治算法。“凡治众如治寡, 分数是也”, 分治策略是分析和解决复杂问题最常用的策略之一。本章根据分治算法的求解步骤把分治策略归纳为三类, 并结合具体实例阐述每类策略的设计思想、 适用范围及实现要点。
    第5章介绍动态规划算法。动态规划算法是最具有创造性的一种算法, 归约、 分治等思维方法都在动态规划算法框架中得到了很好的体现。本章重点讨论基于“划分”和“约简”策略的动态规划算法原理和运用技巧。
    第6章介绍贪心算法。这种类似于“瞎子爬山”的策略, 如果运用适当, 能够快速地产生最优解。本章给出了一些典型的贪心算法问题, 并探讨了贪心算法的适用范围。
    第7章介绍搜索算法。搜索是求解一些难解问题的常用策略, 它把问题求解转换为状态空间图中的路径探索过程, 究其本质, 搜索是一种枚举和优化策略的综合算法。“运用之妙, 存乎一心”, 本章以典型问题为例阐述五种经典搜索策略的原理、 适用范围以及实现要点。
    为便于教学和读者自学, 本教材提供有适用于理论教学的课件以及实践学习的配套平台——“北京交通大学在线程序评测系统”(http:  //acm.bjtu.edu.cn/OnlineJudge , 简称BOJ)。BOJ是一个公益性质的计算机问题求解实践平台, 也是本书的配套网站。本书的例题和习题都以专题的形式加入BOJ题库中, 读者在学习本书时, 可登录该系统进行编程求解和自我评测。
    展开

    作者简介

    本书暂无作者简介
  • 样 章 试 读
  • 图 书 评 价 我要评论
华信教育资源网