查找
查找
1.基本概念
1.查找
在数据集合中寻找满足某种条件的数据元素的过程称为查找
2.查找表
用于查找的数据集合称为查找表,它由同一类型的数据元素(或记录)组成
3.关键字
数据元素中唯一标识该元素的某个数据项的值,使用基于关键字的查找,查找结果应该是唯一的
4.常见操作
1)查找符合条件的数据元素
2)插入、删除某个数据元素
只需要进行操作1,静态查找表,也要进行操作2,动态查找表(除了关注查找速度,也要关注插入、删除是否方便实现)
5.算法性能评价
1、查找长度:在查找运算中,需要对比关键字的次数称为查找长度
2、平均查找长度ASL:所有查找过程中进行关键字的比较次数的平均值。
2.顺序查找
1.算法思想
又称为线性查找,通常用于线性表
2.代码实现
typedef struct{ int *data; int Tablelen; }SSTable; //顺序查找 int Search_Seq(SSTable ST, int key){ int i; for(i = 0; i < ST.Tablelen && ST.data[i] != key; ++i); return i == ST.Tablelen ? -1 : i; }
3.性能分析
1、查找成功:平均查找长度 (n + 1)/2
2、查找失败:平均查找长度 n + 1
3、时间复杂度O(N)
4.优化
1、如果线性表是有序的情况,可以通过折半提高效率
2、对于有序的线性表,如果查找失败,且当前节点大于要查找的节点,则没必要继续往下查找,因此查找长度为 n/2 + n/(n + 1)
3、查找效率需要考虑实际的应用场景
3.折半查找
1.算法思想
又称二分查找,仅适用于有序的顺序表
2.代码实现
//折半查找 int Binary_Search(SSTable L, int key){ int low = 0, high = L.TableLen - 1,mid; while(low <= high){ mid = low + (high - low)/2; if(L.data[mid] == key){ return mid; } else if(L.data[mid] > key){ high = mid - 1; } else{ low = mid + 1; } } return -1; }
3.性能分析
判定树的形态,主要取决于mid是向上取整还是向下取整,上图为向下取整
树高 h = log2(N + 1)
时间复杂度 log2N
4.分块查找
1.算法思想
1、特点:块内无序、块间有序
2、分块查找,又称索引顺序查找,算法过程如下:
1)在索引表中确定待查记录所属的分块(可顺序,可折半)
2)在块内顺序查找(块内是乱序的,所以只能顺序查找)
2.查找效率分析ASL
5.B树
1.m叉查找树
//5叉排序树的结点定义 struct Node{ int keys[4]; //最多4个关键字 struct Node *child[5]; //最多5个孩子 int num; //当前结点中存在几个关键字 };
1.在m叉查找树中,如果每个结点中关键字太少,会导致树变高,要查找更多层结点,效率低
2.为了避免上述问题,规定除了根节点外,任何节点至少有 m/2 个分支,即至少包含 m/2 - 1个关键字(此处的除法均采取向上取整);如5叉排序树中,除关键字外,至少有3个分叉,2个关键字
3.为了避免多叉查找树的不平衡导致查找效率降低的问题,规定任何一个节点,其所有子树的高度都要相同
4.满足以上条件的树是B树
2.B树定义
B树,又称多路平衡查找树,B树中所有节点的孩子个数最大值称为B树的阶,通常用m表示。一颗m阶B树或为空树,或为满足如下特性的m叉树:
1.树中每个节点至多有m颗子树,即至多含有m-1个关键字
2.若根节点不是终端节点(最低一层含有关键字的节点),则至少有两颗子树
3.除根节
4.所有的叶子节点(查找失败的节点)都出现在同一层次上,并且不带信息(可以视为外部结点或类似于折半查找判定树的查找失败节点,实际上这些节点不存在,指向这些节点的指针为空)。
3.B树的高度
1.最小高度
2.最大高度
4.B树的插入
5.B树的删除
6.B+树
1.定义
2.B+树VSB树
1.节点个数、关键字个数
2.查找方式、查找效率
3.子树的个数
注意:在B+树中,非叶节点不含有该关键字对应记录的存储地址。可以使一个磁盘块包含更多个关键字,使得B+树的阶更大,树高更矮,读磁盘次数更少,查找更快
4.典型应用:在MySQL数据库中,使用B+树做索引。
7.散列查找
1.定义
1、散列表,又称哈希表。是一种数据结构,特点是数据元素的关键字与其存储地址直接相关
2、通过哈希函数,建立关键字与存储位置的映射关系。如果通过哈希函数确定的位置已经存放了其他元素,则称这种情况为”冲突“;
2.拉链法
如果可以保证链表有序,可以提高查找效率
3.散列查找
平均查找长度
查找失败的平均查找长度:
散列查找是典型的”用空间换时间“的算法,只要散列函数设计合理,则散列表越长,冲突的概率越低
4.如何设计散列函数
5.开放定址法
1.线性探测法
2.线性探测法查找效率分析
线性探测法很容易造成冲突的”聚集(堆积)”现象,严重影响查找效率,产生原因是:冲突后再探测一定是放在某个连续的位置。
3.平方探测法
4.伪随机序列探测法
5.再哈希法