王道学习
考纲内容
(一)查找的基本概念
(二)顺序查找法
(三)分块查找法
(四)折半查找法
(五)树形查找
二叉搜索树;平衡二叉树;红黑树
(六)B树及其基本操作、B+树的基本概念
(七)散列(Hash)表
(八)查找算法的分析及应用
知识框架
复习提示
本章是考研命题的重点。对于折半查找,应掌握折半查找的过程、构造判定树、分析平均查找长度等。对于二叉排序树、二叉平衡树和红黑树,要了解它们的概念、性质和相关操作等。B树和B+树是本章的难点。对于B树,考研大纲要求掌握插入、删除和查找的操作过程;对于B+树,仅要求了解其基本概念和性质。对于散列查找,应掌握散列表的构造、冲突处理方法(各种方法的处理过程)、查找成功和查找失败的平均查找长度、散列查找的特征和性能分析。
7.1 查找的基本概念
7.2 顺序查找和折半查找
7.2.1 顺序查找
1、一般线性表的顺序查找
2、有序表的顺序查找
7.2.2 折半查找
7.2.3 分块查找
7.2.4 本节试题精选
7.3 树型查找
7.3.1 二叉排序树(BST)
7.3.1.1 二叉排序树介绍
1、二叉排序树的定义
2、二叉排序树的查找
3、二叉排序树的插入
4、二叉排序树的构造
5、二叉排序树的删除
6、二叉排序树的查找效率分析
7.3.1.2 二叉排序树代码
//二叉排序树
#include <stdio.h>
#include <stdlib.h>
struct BSTNode{
//数据域
int key;
//左孩子
struct BSTNode *lChild;
//右孩子
struct BSTNode *rChild;
};
typedef struct BSTNode BSTNode;
typedef struct BSTNode* BSTree;
/*
创建树
*/
BSTree createTree(int key){
BSTNode *newNode=(BSTNode*)malloc(sizeof(BSTNode));
(*newNode).key=key;
(*newNode).lChild=NULL;
(*newNode).rChild=NULL;
BSTree root=newNode;
return root;
}
/*
在二叉排序树中查找值为key的结点--非递归
*/
BSTNode * bstSearchOne(BSTree t, int key){
BSTNode *tempNode=t;
while(tempNode!=NULL&&key!=(*tempNode).key){
if(key<(*tempNode).key){
tempNode=(*tempNode).lChild;
}else{
tempNode=(*tempNode).rChild;
}
}
return tempNode;
}
/*
在二叉排序树中查找值为key的结点--递归
*/
BSTNode * bstSearchTwo(BSTree t, int key){
if(t==NULL){
return NULL;
}
if(key==(*t).key){
return t;
}
if(key<(*t).key){
return bstSearchTwo((*t).lChild,key);
}
if(key>(*t).key){
return bstSearchTwo((*t).rChild,key);
}
}
/*
在二叉排序树中插入值为key的结点--非递归
前提--二叉树中根结点不为空,已有数据
返回值:0--失败 1--成功
*/
int bstInsertOne(BSTree t, int key){
BSTNode *tempNode=t;
BSTNode *node=NULL;
BSTNode *newNode=(BSTNode*)malloc(sizeof(BSTNode));
(*newNode).key=key;
(*newNode).lChild=NULL;
(*newNode).rChild=NULL;
while(tempNode!=NULL){
if(key==(*tempNode).key){
return 0;
}
node=tempNode;
if(key<(*tempNode).key){
tempNode=(*tempNode).lChild;
if(tempNode==NULL){
(*node).lChild=newNode;
return 1;
}
}else{
tempNode=(*tempNode).rChild;
if(tempNode==NULL){
(*node).rChild=newNode;
return 1;
}
}
}
}
/*
在二叉排序树中插入值为key的结点--递归
前提--二叉树中根结点不为空,已有数据
返回值:0--失败 1--成功
*/
int bstInsertTwo(BSTree t, int key){
BSTNode *tempNode=t;
BSTNode *node=NULL;
if(key==(*t).key){
return 0;
}
if(key<(*tempNode).key){
node=tempNode;
tempNode=(*tempNode).lChild;
if(tempNode==NULL){
BSTNode *newNode=(BSTNode*)malloc(sizeof(BSTNode));
(*newNode).key=key;
(*newNode).lChild=NULL;
(*newNode).rChild=NULL;
(*node).lChild=newNode;
return 1;
}
return bstSearchTwo(tempNode,key);
}
if(key>(*tempNode).key){
node=tempNode;
tempNode=(*tempNode).rChild;
if(tempNode==NULL){
BSTNode *newNode=(BSTNode*)malloc(sizeof(BSTNode));
(*newNode).key=key;
(*newNode).lChild=NULL;
(*newNode).rChild=NULL;
(*node).rChild=newNode;
return 1;
}
return bstSearchTwo(tempNode,key);
}
}
int main(){
return 0;
}
7.3.2 平衡二叉树(AVL)
1、平衡二叉树的定义
2、调整最小不平衡子树
3、查找效率分析
4、平衡二叉树的删除
7.3.3 红黑树
1、红黑树的定义和性质
2、红黑树的插入
3、红黑树的删除
7.3.4 本节试题精选
7.4 B树和B+树
考研大纲对B树和 B+树的要求各不相同,重点在于考查B树,不仅要求理解B树的基本特点,还要求掌握B树的建立、插入和删除操作,而对B+树则只考查基本概念。
7.4.1 B树的介绍
B树的高度(碰盘存取次数)
B树中的大部分操作所需的磁盘存取次数与B树的高度成正比
7.4.2 B树的插入和删除
插入
删除
7.4.3 B+树
7.4.4 本节试题精选
7.5 散列表
7.5.1 散列表的基本概念
在前面介绍的线性表和树表的查找中,查找记录需进行一系列的关键字比较,记录在表中的位置与记录的关键字之间不存在映射关系,因此在这些表中的查找效率取决于比较的次数。
散列函数(也称哈希函数):一个把查找表中的关键字映射成该关键字对应的地址的函数,记为Hash(key) =Addr(这里的地址可以是数组不标、索引或内存地址等)。
散列函数可能会把两个或两个以上的不同关键字映射到同一地址,称这种情况为冲突,这些发生碰撞的不同关键字称为同义词。一方面,设计得好的散列函数应尽量减少这样的冲突;另一方面,由于这样的冲突总是不可避免的,所以还要设计好处理冲突的方法。
散列表(也称哈希表):根据关键字而直接进行访问的数据结构。也就是说,散列表建立了关键字和存储地址之间的一种直接映射关系。
理想情况下,对散列表进行查找的时间复杂度为O(1),即与表中元素的个数无关。下面分别介绍常用的散列函数和处理冲突的方法。
7.5.2 散列函数的构造方法
在构造散列函数时,必须注意以下几点:
1)散列函数的定义域必须包含全部关键字,而值域的范围则依赖于散列表的大小。
2)散列函数计算出的地址应尽可能均匀分布在整个地址空间,尽可能地减少冲突。
3)散列函数应尽量简单,能在较短的时间内计算出任意一个关键字对应的散列地址。
下面介绍常用的散列函数。
7.5.3 处理冲突的方法
7.5.4 散列查找及性能分析
7.5.5 本节试题精选