查找表
- 查找表(Search Table)是由同一类型的数据元素(或记录)构成的集合。
- 关键字(Key)是数据元素中某个数据项的值,又成为键值,用它可以标识一个数据冤死,也可以标识一个记录的某个数据项。
- 若某关键字可以唯一的标识一个记录,则称此关键字为主关键字(Primary Key),这就意味着不同的记录主关键字均不同。
- 对于那些可以标识多个元素(或记录)的关键字,成为次关键字(Secondary Key)。
查找
就是根据给定的某个值,在查找表中确定一个其关键字等于给定值的数据元素(或记录)。
静态查找表
表示只作查找操作的查找表,其主要操作有:
- 查询某个“特定的”数据元素是否在查找表中
- 检索某个“热定的”元素和各种属性
动态查找表
在查找过程中同时插入查找表中不存在的数据元素,或者从查找表中删除已经存在的某个数据元素。其操作也是两个:
- 查找时插入数据元素
- 查找时删除数据元素
为了提高查找效率,查找所基于的数据结构是集合,集合中的记录之间没有本质关系。为了提高性能,要在存储时将查找集合组织成表、树结构。
如:静态查找表比较适合线性表,动态查找比较适合二叉排序树。
顺序查找
又叫线性查找,是最基本的查找技术,其查找过程是:从表中第一个(或最后一个)开始,逐个进行记录的关键字和给定值比较,若某个记录的关键字和给定值相等,则查找成功,找到所查的记录;如果直到最后一个(或者第一个)记录,其关键字都与给定值不相等,则表中没有所查的记录,查找失败。
对这种算法来说,最好的情况是第一个位置就找到了,算法复杂度为O(1)
,最坏是最后一个才找到,算法时间复杂度O(n)
,找不到的话需要n+1
次比较,时间复杂度也是O(n)
。关键字在任一位置的概率是相同的,平均查找次数为(n+1)/2
,终上,其算法复杂度为O(n)
。
有序表查找
折半查找(Binary Search)
又称二分查找,前提是线性表中的记录必须是关键码有序(通常是由小到大),线性表必须采用顺序存储。基本思想为:在有序表中,取中间记录为比较对象,若给定值与中间记录的关键值相等,则查找成功;若给定值小于中间记录的关键值,则在中间记录的左半区继续查找;否则在右半区继续查找。不断重复上述过程,直到查找成功,或所有查找区域无记录,查找失败为止。
算法复杂度为O(logn)
,远远好于顺序查找的O(n)。
插值查找(Interpolation Search)
是根据要查找的关键字key与查找表中最大最小记录的关键字比较后的查找算法,其核心是插值计算公式
key−a[low]a[high]−a[low]
,其中key
是关键字,a[low]
、a[high]
是查找数组的首末元素。
算法复杂读也是O(logn)
,但对于表长较大,而关键字分布又比较均匀的查找表来说,其平均性能比折半查找要好的多。
线性索引查找
索引查找是居于关键字无序的情况下产生的,毕竟现实中有序的关键字很少,大部分都是无序的。
索引就是把一个关键字与它对应的记录相关联的过程,一个索引由若干个索引项构成,每个索引项至少应包含关键字和其对应的记录在存储器的位置等信息。
稠密索引
稠密索引是指在线性索引中,将数据集中的每个记录对应一个索引项,对于稠密索引这个索引表来说,索引项一定是按照关键码有序排列。
分块索引
是把数据集的记录分成了若干块,并且这些块需要满足两个条件:
- 块内无序,即每一个块内不要求有序
- 块间有序,只有块间有序,才可能在查找时带来效率。
在分块索引表中查找,分两步进行:
1. 在分块索引中查找要查关键字所在的块。由于分块索引的块间有序,因此很容易使用折半,插值等算法。
2. 根据块首指针找到相应的块,并在块中顺序查找关键码。因为块中可以是无序的,因此只能顺序查找。
倒排索引
索引项的通用结构为:
- 次关键码
- 记录号表
其中记录号表存储具有相同次关键字的所有记录的记录号(可以是指向记录的指针或者是该记录的主关键字)。这样的索引方法就是倒排索引(inverted index)
如:由要查找的单词去查找文章序号就是倒排,因为是从单词出发,而不是从文章出发去查找单词。
二叉排序树
二叉排序树(Binary Sort Tree),又称为二叉查找树。它或者是一棵空树,或者具有以下性质的二叉树
- 若它的左子树不空,则左子树上的所有结点的值均小于它的根结点的值;
- 若它的右子树不空,则右子树上的所有结点的值均大于它的根结点的值;
- 它的左右子树也分别为二叉排序树
二叉树是以链接的方式存储,保持了链接存储结构在执行插入或删除操作时不用移动元素的优点,只要找到合适的插入和删除位置后,仅需要修改链接指针即可。
在最好情况下最少为1次,即根结点就是要找的结点,最多也不会超过树的深度。也就是说,二叉排序树的查找性能取决于二叉排序树的形状,因此,如果二叉树是平衡,即其深度最少时性能最好。
平衡二叉树
平衡二叉树(Self-Balancing Binary Search Tree或Height-Balanced Binary Search Tree),是一种二叉排序树,其中每一个结点的左子树和右子树的高度差最多为1。
平衡因子(Balance Factor)是二叉树上结点的左子树深度减去右子树深度的值,平衡二叉树的所有结点的平衡因子只可能是-1、0和1,只要二叉树有一个结点的平衡因子的绝对值大于1,就不是平衡二叉树。
距离插入结点最近的,且平衡因子的绝对值大于1的结点为根的字数,我们称为最小不平衡子树。
多路查找树(B树)
多路查找树(Muilti-Way Search Tree)是专门为了内外存储设备协同工作所设计的。其每一个结点的孩子数可以多于两个,且每一个结点处可以存储多个元素。
- 2-3树是这样的一棵多路查找树:其中的每一个结点都具有两个孩子(称为2结点,有一个元素两个孩子或没有孩子)或三个孩子(3结点有两个元素三个孩子或没有孩子)。
- 2-3-4树:比2-3树多了4结点的使用,4结点包括大中小三个元素和四个孩子或没有孩子。
- B树:是一种平衡的多路查找树,2-3树和2-3-4树都是B树的特例,结点最大的孩子数目称为B树的阶,因此,2-3树是3阶树,2-3-4树是4阶树。一棵m阶的B树有以下属性:
- B+树:是B树的拓展,一棵m阶B+树和m阶B树的差异为:
- 有n棵子树的结点包含有n个关键字
- 所有的叶子结点包含全部关键字的信息,及指向含有这些关键字记录的指针,叶子结点本身依关键字的大小自小而大顺序链接
- 所有分支结点都可以看作是索引,结点中仅含有其子树的最大(或最小)关键字。
散列表查找
散列技术是在记录的存储位置和它的关键字之间建立一个确定的对应关系f,使得每个关键字key对应一个存储位置f(key)
。查找时,通过key的映射f(key)
找到对应的位置。
把这种对应关系f称为散列函数,又称为哈希(Hash)函数,采用散列技术将记录存储在一块连续的存储空间中,这块连续存储空间称为散列表或哈希表(Hash Table)。