7.0 知识回顾
7.1 查找的概念
注意:基本概念要经常回顾,尤其是在学完本章之后,这样便于深入理解基本概念,构建整章的知识体系。
松散的关系:没有严格的前驱和后继,所以查找表可以有不同的存储结构。
7.2 线性表的查找
7.2.1 顺序表的顺序查找
7.2.2 折半查找(二分查找)
折半查找的时间复杂度是对数级lgn
7.2.3 分块查找
7.3 树表的查找
7.3.1 二叉排序树
1)概念
局部上:左子树 < 根 < 右子树,但是整体上“所有结点”还是要满足二叉排序树的定义。
2)查找
3)插入
二叉排序树插入算法:
//二叉排序树的插入操作
void InsertBST_Real(BSTree& T, keytype key) {
if (!T) {
T = new BSTNode;
T->data.key = key;
T->lchild = NULL;//创建一个新树,不仅要给数值域赋值,还要记得给左右孩子的指针域赋值!!
T->rchild = NULL;//错误点:忘记左右孩子指针域的赋值,TMD!
}
else if (key < T->data.key)
InsertBST_Real(T->lchild, key);
else if (key > T->data.key)
InsertBST_Real(T->rchild, key);
}
4)生成
重点:
生成二叉排序树就是不断地执行 “二叉排序树插入操作”。
二叉排序树生成算法:
//二叉排序树的插入操作
void InsertBST_Real(BSTree& T, keytype key) {
if (!T) {
T = new BSTNode;
T->data.key = key;
T->lchild = NULL;//创建一个新树,不仅要给数值域赋值,还要记得给左右孩子的指针域赋值!!
T->rchild = NULL;//错误点:忘记左右孩子指针域的赋值,TMD!
}
else if (key < T->data.key)
InsertBST_Real(T->lchild, key);
else if (key > T->data.key)
InsertBST_Real(T->rchild, key);
}
//二叉排序树的生成
void CreatBST_Real(BSTree& T, keytype key[], int n) {
for (int i = 0; i < n; i++) {
InsertBST_Real(T, key[i]);
}
}
中序遍历二叉排序树,就可以获得升序序列。
5)删除
判断是否为叶子结点:判断左右孩子是否都为空。
以下只是用代码的形式来表示上面的例子,具体程序还需要更多的判断语句。
if(T->rchild->data.key == 80);
T->rchild = T->rchild->rchild;
7.3.2 平衡二叉树
1)定义
调整原则非常重要!
Tips:找到大小位于中间的提上去就行
2)LL调整
3)RR型
4)LR型
不懂就看视频p151 11:00
5)RL型
6)例题
综上,构成了一个查找性能最好的二叉排序树。
7.4 散列表上的查找
7.4.1 散列表的基本概念
7.4.2 散列函数的构造方法
7.4.3 如何解决“冲突”
1.开放定址法(开地址法)
1)线性探测法
查找时,首先将查找对象mod11,看结果的地址中的元素是否等于查找对象,等于的话输出地址,不等于的话将地址加1,再判断是否找到,按照线性探测法的规定,直到找到或者遇到空位置为止。
2) 二次探测法
3) 伪随机探测法
2. 链地址法(拉链法)
7.4.4 散列表的查找
7.4.5 散列表平均查找长度(ASL)
7.4.6 结论
查找性能:散列表 > 二分查找 > 顺序查找