文章目录
一、集合的基本概念
1、集合的特征
- 集合具有无序性,集合中的数据元素除了属于同一集合之外,没有任何逻辑关系。
- 集合具有互异性,在集合中,每个数据元素有一个区别于其他元素的唯一标识,通常称为键值或关键字值
2、集合元素的类型
以学生信息集合为例,每一个元素是一个学生的相关数据,可能包含很多信息,但学号是关键字。
template<class KEY,class OTHER>
struct SET{
KEY key;//关键字
OTHER other;//包含姓名、性别、出生日期等信息
};
3、集合的主要运算
- 查找某一元素是否存在
- 按其关键字进行排序
集合的存储: - 任何容器都能存储集合
- 常用的表示形式是借助于线性表或树
- 唯一一个仅适合于存储和处理集合的数据结构是散列表
二、查找的基本概念
查找是对数据最常见的操作。
常见查找表的分类如下:
- 静态查找表
若内存中数据相对稳定、鲜有变化,则称数据是静态的,这组数据称为静态查找表,查找技术称静态查找技术。
静态数据的存储仅需朝着有利于查找的目标来完成,最便利的存储方式是顺序存储 - 动态查找表
若数据不太稳定、有频繁的插入、删除操作,则称这组数据是动态的,它被称为动态查找表,相应的查找技术称为动态查找技术。
动态数据的存储既要有利于数据的查找操作,也要有利于数据的插入、删除操作,一般采用链式存储 - 内部查找
集合元素可以一次性全部放入内存,典型标志是有个数组或链表可存储全部数据 - 外部查找
集合元素多,无法一次性全部读入内存,需要分批
这篇文章将主要介绍静态查找表。剩下的三种查找表形式将在后续介绍。
三、静态表的查找
1. 无序表的查找
- 无序表: 数组中的元素是无序的
- 无序表的查找:只能做线性的顺序查找
- 顺序查找的优化:利用哨兵减少n次比较(找到就停止查找)
template<class KEY,class OTHER>
int seqSearch(SET<KEY, OTHER> data[], int size, const KEY& x) {
data[0].key = x;
for (int i = size; x != data[i].key; --i);
return i;
}
2. 有序表的查找
2.1 顺序查找
- 与无序表中的顺序查找类似
- 当被查元素在表中不存在时,不需要查到表头
//有序表的顺序查找,默认数据由小到大排列
template<class KEY, class OTHER>
int seqSearch(SET<KEY, OTHER> data[], int size, const KEY& x) {
data[0].key = x;
for (int i = size; x < data[i].key; --i);
if (x == data[i].key)return i;
else return 0;
}
2.2 二分查找
- 每次检查待查数据中排在最中间的那个元素
- 如中间元素等于要查找的元素,则查找完成 否则,确定要找的数据是在前一半还是在后一半,然后缩小范围,在前一半或后一半内继续查找。
//有序表的二分查找
template <class KEY, class OTHER>
int binarySearch(SET<KEY, OTHER> data[],
int size, const KEY& x) {
int low = 1, high = size , mid;
while (low <= high) {
mid = (low + high) / 2;
if (x == data[mid].key) return mid;
if (x < data[mid].key)high = mid - 1;
else low = mid + 1;
}
return 0;
}
2.3 插值查找
- 适用于数据的分布比较均匀的情况
- 利用数据分布的均匀性进行所找数值的位置估计
2.4 分块查找
- 分块查找也称为索引顺序块的查找。
- 是处理大量数据查找的一种方法。
- 它把整个有序表分成若干块,块内的数据元素可以是有序存储,也可以是无序的,但块之间必须是有序的。
查找由两个阶段组成:查找索引和查找块
四、总结
- 介绍了集合关系的基本概念,以及集合类型的数据结构中的基本操作。
- 针对静态的集合,介绍了查找操作的实现。包括顺序查找、二分查找、插值查找和分块查找。