(读者笔记:以上就是“抽象”,将问题符号化、抽象化、简单化!)
算法设计中一些常见的通用想法,可以成为算法设计模式。常见模式包括:
Python程序中的很多基本操作不是常量时间。
下面是一些基本情况:
这里先列举一些具体的操作:
(读者补充:以上的“关键码”,应该是指字典的“键”(key)。)
人们总结出的一批特别有用的典型数据结构,主要有:
用数据结构存储信息,不仅要考虑如何把抽象的数据结构映射到计算机或程序可以表达和操作的数据存储形式,还要考虑作用于具体数据结构的各种操作,如结构的建立,其中元素的访问、插入或删除元素等一般的操作。在实际使用中,经常还需要考虑一些面向具体应用问题的特殊操作。
结构性的数据结构:如线性结构、树结构和图结构。这些数据结构都对数据元素之间的相互关系做出了一些规定,元素之间确实满足某种关系才能被称为线性结构和树结构等。这些数据结构的最重要的特征就是它们的结构。
(这一段应该说的是“功能性的数据结构”)本书中还将讨论另一类数据结构,它们并没有对其元素的相互关系提出任何结构性的规定,而是要求实现某种计算中非常有用的功能。作为可以包含一批数据元素的结构,最基本的要求就是支持元素的存储和使用(使用也常称为元素访问)。这个基本要求实际上是功能性的要求,而非结构性的要求,因为它完全不涉及元素如何存储、元素之间如何关联。
补充:支持元素存储和访问的数据结构被称为容器。
下面的讨论中,涉及的功能性数据结构包括栈、队列、优先队列、字典等。这些结构都支持以某一套方式存储和访问元素(包括删除元素)。
由于只有功能要求,这类数据结构可以采用任何技术实现。实际中人们通常首先把这类结构*映射到某种结构性的数据结构,而后采用相应的实现技术*。
一个程序在运行中将不断建立一些对象并使用它们。建立的每个对象都有一个确定的唯一标识,用于识别和使用这个对象。在对象的存续期间,其标识保持不变,这也是一个基本原则。例如,Python**标准函数id**取得对象的标识,内置操作is和is not通过比较标识的方式判断是否为同一个对象。在具体系统里用什么作为对象标识,是系统设计者的考虑和选择。最简单的方式就是直接使用对象的存储位置(内存地址)。这显然是一种唯一的标识,因为不会有两个不同对象存放在同一个存储位置。
在编程语言的层面,知道了一个对象的标识就可以直接访问(使用)它。已知对象标识(无论它是否直接为对象地址),访问相应对象的操作可以直接映射到已知地址访问内存单元,这种操作可以在常量时间完成(是O(1)时间操作)。
在计算机内存里表示数据元素之间的联系,只有两种基本技术:
(读者补充:“对象关联的表示”这一小节建议详细看,我就不截图了。)
高级语言里的变量(全局变量、函数的局部变量和参数)是内存及其地址的抽象。变量本身也需要在内存中安排位置,每个变量占用若干存储单元。语言系统需要有一套系统化的安排方式处理这个问题,下面的讨论中不考虑。为了理解程序的行为,只需要假定在程序运行中总能找到根据作用域可见的变量,取得或修改它们的值。
Python语言的实现基于一套精心设计的链接结构。变量与其值对象的关联通过链接的方式实现,对象之间的联系同样也可以通过链接。一个复杂对象内部也可能包含几个子部分,相互之间通过链接建立联系。例如,如果一个list里包含了10个字符串,那么在实现中,在这个list对象里就会记录这10个字符串的链接关系(参看图1.10)。
(读者补充:这里的“关键码”,应该是指“键”,即key。)
未完待续。。
参考文献:
1.《数据结构与算法-Python语言描述》。