编辑推荐
探秘算法世界、求索数据结构之道
汇集经典问题、畅享编程技法之趣
点拨求职热点、敲开业界名企之门 ;
内容简介
本书以现代计算机常用的十八种数据结构为线索,结合C++中的STL编程实践,详细介绍了四大算法设计思想(贪心法、动态规划、分治法、回溯法)、二十大经典问题和四十二个重要算法。具体涉及的数本书围绕算法与数据结构这个话题,循序渐进、深入浅出地介绍了现代计算机技术中常用的40 余个经典算法,以及回溯法、分治法、贪婪法和动态规划等算法设计思想。在此过程中,本书也系统地讲解了链表(包括单向链表、单向循环链表和双向循环链表)、栈、队列(包括普通队列和优先级队列)、树
(包括二叉树、哈夫曼树、堆、红黑树、AVL 树和字典树)、图、集合(包括不相交集)与字典等常用数据结构。同时,通过对22 个经典问题(包括约瑟夫环问题、汉诺塔问题、八皇后问题和骑士周游问题等)的讲解,逐步揭开隐匿在数据结构背后的算法原理,力图帮助读者夯实知识储备,激活思维技巧,并*终冲破阻碍编程能力提升的重重藩篱。
作者简介
左飞服务于中国规模*的移动通信运营商,业余时间他撰写了多部计算机方面的著作,并译有《编码》、《提高C++性能的编程技术》等经典名著。
目录
与数据结构 ..................................................................................... 1
1.1.1 数据及其类型 ................................................................................................. 1
1.1.2 数据结构简介 ................................................................................................. 3
1.2 算法 ......................................................................................................... 5
1.2.1 算法的概念 ..................................................................................................... 5
1.2.2 算法的分析 ..................................................................................................... 8
1.2.3 算法的设计 ................................................................................................... 12
1.3 C++中的STL ........................................................................................ 18
1.3.1 STL 简介 ...................................................................................................... 19
1.3.2 STL 构成 ...................................................................................................... 20
1.3.3 STL 的不同版本 ........................................................................................... 22
本章参考文献 ................................................................................................ 23
第2 章 指针与数组——也谈中国古代兵制 ................................ 24
2.1 指针 ....................................................................................................... 24
2.1.1 内存与地址 ................................................................................................... 24
2.1.2 指针的语法 ................................................................................................... 27
2.1.3 使用指针变量 ............................................................................................... 29
2.1.4 函数与参数传递 ........................................................................................... 31
2.2 数组 ....................................................................................................... 36
2.2.1 结构型数据类型 ........................................................................................... 37
2.2.2 数组定义与初始化 ....................................................................................... 37
2.2.3 数组与指针 ................................................................................................... 41
2.2.4 数组的抽象数据类型 ................................................................................... 45
2.3 数组应用举例 ....................................................................................... 48
2.3.1 Z 字形编排问题 ........................................................................................... 48
2.3.2 大整数乘法问题 ........................................................................................... 51
2.3.3 九宫格问题 ................................................................................................... 52
2.4 动态内存管理 ....................................................................................... 53
2.4.1 关键词new 和delete .................................................................................... 53
2.4.2 避免内存错误 ............................................................................................... 56
本章参考文献 ................................................................................................ 61
第3 章 字符串与模式匹配——梦里寻她千百度 ......................... 62
3.1 基本概念与定义 ................................................................................... 62
3.1.1 C++中的字符串 ............................................................................................ 62
3.1.2 字符串抽象数据类型 ................................................................................... 65
3.2 文本的精确匹配 ................................................................................... 66
3.2.1 BF 算法 ......................................................................................................... 66
3.2.2 MP 算法 ........................................................................................................ 67
3.2.3 KMP
前沿
前言
2014 年的冬天,一部讲述计算机科学之父艾伦·图灵传奇人生的传记电影在美国上映,这部影片就是《模仿游戏》。次年,该片荣获第87 届奥斯卡金像奖**改编剧本奖,以及包括**影片、**导演、**男主角、**女配角在内的7 项提名,一时风光无限。尽管现代计算机已经无处不在,但因图灵的时代离我们过于久远,现今人们对他的研究工作已经知之甚少。
要说起图灵的贡献,我们还得把时间再往前推。1900 年,德国数学家大卫·希尔伯特在巴黎举行的国际数学家大会上做了题为《数学问题》的演讲,在这篇重要的演讲中,他提出了著名的希尔伯特之23 个问题。尽管此后的数学发展远远超过了希尔伯特的预料,但他所提出的23 个问题仍然对20 世纪的数学发展起到了非常积极的推动作用。
希尔伯特的第10 个问题是要设计一个算法来测试多项式是否有整数根。他没有使用算法这个术语,而是采用了下面这种表述:“通过有限多次运算就可以决定的过程”。有意思的是,从希尔伯特对这个问题的陈述可以看出,他明确地要求设计一个算法。因此,他显然是假设这样的算法是存在的,人们所要做的只是找到它。现在我们知道,这个任务是无法完成的,即它是算法上不可解的。但对那个时期的数学家来说,以他们对算法的直观认识,得出这样的结论是不可能的。
非形式地说,算法是为实现某个任务而构造的简单指令集。以日常用语来说,算法又称为过程或者方法。算法在数学中也起着非常重要的作用。古代数学文献中就包含有执行各种各样计算任务的算法描述。例如,我国古代数学经典《九章算术》中就记述了包括求**公约数、*小公倍数、开平方根、开立方根等在内的诸多算法。现代计算机科学中更是充满了各种各样的算法。例如,求解*短路径的狄克斯特拉算法,进行字符串匹配的KMP 算法等。
虽然算法在数学中已有很长的历史,但在20 世纪之前,算法概念本身一直没有精确的定义。数学家们面对希尔伯特的第10 个问题,显得束手无策。由于缺乏对于算法本身的精确定义,所以要证明某个特定任务不存在算法则完全不可能。要想破解希尔伯特的第10 个问题,人们不得不等待算法之精确定义的出现。
直到1936 年,曙光似乎出现了。图灵向伦敦的权威数学杂志递交了一篇题为《论数字计算在决断难题中之应用》的论文。该文*终于1937 年正式发表,并立即引起了广泛的注意。在论文中,图灵描述了一种可以辅助数学研究的机器,也就是后来被称为“图灵机”的抽象系统。与此同时,另外一位数学家阿隆佐·丘奇也独立地提出了另外一套系统,即所谓的λ演算。图灵采用他的图灵机来定义算法,而丘奇则采用λ演算来定义算法,后来图灵证明这两个定义是等价的。由此,人们在算法的非形式概念和精确
定义之间建立了联系,即算法的直觉概念等价于图灵机算法,这就是所谓的丘奇-图灵论题。
丘奇-图灵论题提出的算法定义是解决希尔伯特第10 个问题所必需的。而第10 个问题的真正解决则要等到1970 年,借助于丘奇与图灵的杰出贡献,马提亚塞维齐在戴维斯、普特纳姆和罗宾逊等人工作的基础上,*终证明检查多项式是否有整数根的算法是不存在的。
从图灵开始,算法已然同计算机科学之间产生了密不可分的联系。当然,本书的内容并不打算从图灵机开始讲起。回顾建立算法形式化定义和破解希尔伯特第10 个问题的那段风起云涌的历史,更多地是想说明算法之于我们的世界是多么重要。
无论你是信息技术的从业人员,还是计算机专业的在校学生,再或者是从事相关专业的研究人员,熟练掌握一门计算机语言的重要性都不言而喻。但是不是掌握了这其中的语法规则就能写出漂亮的程序了呢?答案当然是否定的。因为你还需要另外一样至少同等重要的工具——算法。算法和语言的关系,其实很像是“道”和“术”的关系。掌握一门语言,就如同习得一门技艺,可以成为一名工匠。但要想从工匠一跃成为大师,单单停留在“术”的层面显然不够,更重要的是悟“道”。而算法无疑就是计算机程序设计中的“道”。
谈到算法的重要性就不得不提及计算机科学家安德鲁·艾派尔在1985 年所开展的一项研究工作,这也是程序性能优化领域的经典案例。彼时,艾派尔编写了一个用于计算重力场中天体间相互作用之问题的程序。给定场中物体质量、初始位置和速度等条件,该程序即可对10000 个天体相互作用时其中两个天体的运行状态进行模拟和仿真。由于计算量太大,*初的程序要完成该项计算大约需要耗时一年。在一系列的改进之后,艾派尔*终将程序耗时有效地缩短到了一天!而在这个改进过程中,算法和数据结构的调优占了主要比重。
再说一个发生在笔者身上的例子。曾经在上学的时候,老师布置了一道编程作业,用于模拟一个猜三和弦的游戏。一个三和弦是指从A、B、C、D、E、F、G 这7 个音中任选3 个组成的一个旋律,而每个音又有高音、中音、低音3 种情况(分别用1、2、3 来表示)。现在假设一名作曲家心中有了一个心仪的旋律,然后一个钢琴演奏者试图猜测这个答案。每当演奏者给出一个猜测,例如“A1、B2、C3”。那么作曲家将只能答复这其中完全猜中的音调(即音符和音高都猜对)有几个,除了完全猜中的音调以
外,音符猜中了几个,音高猜中了几个。然后演奏者继续猜测,直到完全猜中为止。要知道,全部的组合可能有1330 种之多!而我们希望用越少的次数猜中越好。不知道本书的各位读者心中是否已想到什么方法来解决这个问题。不过笔者*终实现的程序可以做到平均4.2 次便猜中答案。而在这个过程中,设计一个绝佳的算法无疑是不二之选。
说起算法又不得不提及数据结构,二者是相辅相成、密不可分的。一方面,算法一定要借助相应的数据结构才能得以实现,另一方面我们在定义一个数据结构的同时其实也已经定义了与之相关的操作。这些操作本身执行的步骤就是算法。
总的来说,本书围绕算法与数据结构这个话题,循序渐进、深入浅出地介绍了现代计算机技术中常用的40 余个经典算法(包括模式匹配算法、排序算法、散列算法、*短路径算法等),以及回溯法、分治法、贪婪法和动态规划等算法设计思想。本书也系统地讲解了链表(包括单向链表、单向循环链表和双向循环链表)、栈、队列(包括普通队列和优先级队列)、树(包括二叉树、哈夫曼树、堆、红黑树、AVL 树和字典树)、图、集合(包括不相交集等)与字典等常用数据结构。同时,通过对22 个经典问题(包括约瑟夫环问题、汉诺塔问题、八皇后问题和骑士周游问题等)的讲解,逐步揭开隐
匿在数据结构背后的算法原理,力图帮助读者夯实知识储备,激活思维技巧,并*终冲破阻碍编程能力提升的重重藩篱。
更值得一提的是,算法与数据结构知识是技术类求职过程中的必考内容。希望广大读者,尤其是处于求职应聘阶段的毕业生,在夯实基础、培养能力的同时,亦能设法将知识转化为生产力,求得一份称心如意的职位。若能事半功倍、一石二鸟,何乐而不为?为此,笔者特别在附录中整理出了一些求职面试中的经典题目,供有相关需求的读者参考学习。该套题目主要以算法与数据结构问题为主线,并穿插以C/C++相关的编程问题,具有较高的实用性,对提高应聘竞争力很有帮助。特别地,在正文中涉及相关考点之处,笔者均采用旁注的形式点明了可以参考的题目编号,便于读者在阅读过程中,边学边练,知行合一。
纸上得来终觉浅,绝知此事要躬行。锤炼数据结构的运用能力和深化算法思想的理解程度都有赖于编程实践活动。本书采用C++作为描述语言,并提供有涉及的全部数据结构和算法之实现代码,供读者参考学习。这些代码均在基于TDM-GCC 4.9.2 的DEV-C++ 5.11 和Visual Studio 2013 环境下编译通过。本书特别提供了一个在线支持资源,地址http://blog.csdn.net/baimafujinji,从中读者可以下载得到全书的配套代码和附录题库的参考答案,本书的勘误也将实时发布在此博客上。同时欢迎读者就本书中的
问题和不足与笔者展开讨论,有关问题请在上述博客中留言。
*后,刘航、吴凯、姜萌、何鹏、胡俊、李召恒、初甲林等人也参与了本书编写工作,笔者在此表示由衷的感谢。
自知论道须思量,几度无眠一文章。由于时间和能力有限,书中纰漏在所难免,真诚地希望各位读者和专家不吝批评斧正。
算法之美——隐匿在数据结构背后的原理(C++版) pdf下载声明
本pdf资料下载仅供个人学习和研究使用,不能用于商业用途,请在下载后24小时内删除。如果喜欢,请购买正版