第8章 字典和集合
8.1 数据存储、检索和集合
8.1.1 数据存储和检索
概述
在一些专业书籍或编程语言里,字典也被称为查找表、映射或者关联表等。
字典操作和效率
字典和索引
8.1.2 字典实现的问题
字典抽象数据类型
对于动态字典,还需支持插入和删除元素。
字典元素:关联
一个数据项就是一种二元组,下面称之为关联。
为了下面讨论的方便,现在首先定义一个关联对象的类Assoc,假定本章下面讨论的字典都以Assoc对象为元素:
class Assoc:
def __init__(self, key, value):
self.key = key
self.value = value
def ___lt__(self, other): # 有时(有些操作)可能需要考虑序(表示less than)
return self.key < other.key
def __le__(self, other):
return self.key < other.key or self.key == other.key
def __str__(self): # 定义字符串表示形式便于输出和交互(表示less than or equal to)
return "Assoc({0}{1})".format(self.key, self.value)
字典的实现
8.2 字典线性表实现
8.2.1 基本实现
8.2.2 有序线性表和二分法检索
在元素有序的表上做二分法检索的函数可定义如下:
def bisearch(lst, key):
low, high = 0, len(lst) - 1
while low <= high: # 范围内还有元素
mid = low + (high - low) // 2
if key == lst[mid].key:
return lst[mid].value
if key < lst[mid].key:
high = mid - 1 # 在低半区继续
else:
low = mid + 1 # 在高半区继续
可以继承前面基于表的字典类,定义一个新的字典类:
class DictOrdList(DictList):
......
def search(self, key):
......
def insert(self, key, data):
......
def delete(self, key):
......
......
# end of class
二分法检索实例
算法分析
8.2.3 字典线性表总结
问题和思考
8.3 散列和散列表
首先讨论散列技术及其在字典方面的应用,即所谓的散列表(hash table)。
8.3.1 散列的思想和应用
散列思想在信息领域的应用
散列技术:设计和性质
这说明,在通常情况下,散列函数h是一个从大集合到小集合的映射。
8.3.2 散列函数
用于整数关键码的若干散列方法
数字分析法:
折叠法:
中平方法:
通俗地讲,散列函数的映射关系越乱越好,越不清晰越好
常用散列函数
两种常用的散列函数:
- 除余法,适用于整数关键码。
- 基数转换法,适用于整数或字符串关键码。
下面是用Python写出的一个字符串散列函数:
def str_hash(s):
h1 = 0
for c in s:
h1 = h1 *29 + ord(c)
"""
ord(c, /)
Return the Unicode code point for a one-character string.
示例:
>>> ord('a')
97
"""
return h1
8.3.3 冲突的内消解:开地址技术
(读者:这一小节没有仔细看,下次好好看。)
冲突消解方法:
- 内消解方法(在基本的存储区内部解决冲突问题)。
- 外消解方法(在基本的存储区之外解决冲突)。
开地址法和探查序列
开地址法示例
检索和删除
8.3.4 外消解技术
溢出区方法
桶散列
(读者:这里没仔细看。)
8.3.5 散列表的性质
扩大存储区,用空间交换时间
负载因子和操作效率
可能技术和实用情况
8.4 集合
8.4.1 集合的概念、运算和抽象数据类型
概念和集合描述
集合运算
抽象数据类型
8.4.2 集合的实现
简单线性表实现
排序顺序表实现
假设需要求交集的集合S和T由两个Python的表s和t表示,结果集合用表r表示。求交集的算法(注意,这里假设s和t的元素都从小到大排列):
r = []
i = 0 # i和j是s和t中下一次检查的元素的下标
j = 0
while i < len(s) and j < len(t):
if s[i] < t[j]:
i += 1
elif t[j] < s[i]:
j += 1
else: # s[i] = t[j]
r.append(s[i])
i += 1
j += 1
# 现在r就是得到的交集
散列表实现
8.4.3 特殊实现技术:位向量实现
(读者:这一小节没看)
8.5 Python的标准字典类:
8.6 二叉排列树和字典
(读者:没看)
8.6.1 二叉排列数
定义和性质
二叉排序树上的检索
二叉排序树(字典)类
性质分析
8.6.2 最佳二叉排列数
平均检索长度
简单情况:检索概论相同
8.6.3 一般情况的最佳二叉排列数
问题和性质
构造方法
计算带权路径长度
算法设计和实现
算法分析
8.7 平衡二叉树
(读者:没看)
8.7.1 定义和性质
8.7.2 AVL树类
基本定义
8.7.3 插入操作
插入后的失衡和调整
插入操作示例
总结和分析
插入操作的实现
8.7.4 相关问题
插入操作的复杂度
删除操作
几种二叉树排序的对比
8.8 动态多分支排列树
(读者:没看)
8.8.1 多分支排列树
8.8.2 B树
例子和定义
操作
B树的应用
8.8.3 B+树
本章总结
练习
参考文献:
1.《数据结构与算法-Python语言描述》。