查找的基本概念
- 查找方法的选取依赖于:
1、查找表的数据结构:即采用顺序存储结构还是链式存储结构
2、查找表中关键字的次序:有序还是无序 - 查找的算法时间复杂度分析
采用平均查找长度ASL,即关键字的平均比较字数对查找算法进行分析。类似于时间复杂度中的f(n).
ASL = (c1 + c2 + … + cn) * (1/n)
ci表示查找到第i个记录要进行的比较次数;1/n表示查找到每一个记录的概率。
顺序查找法
1、概念介绍:从表的一端开始,顺序扫描线性表,将表中的关键字依次与给定的记录比较
2、算法实现:简单
3、平均查找长度:ASL= (1 + 2 + … + n)/n
折半查找法
1、算法介绍:折半查找要求带查找的序列是有序的;首先确定有序序列的中间位置,然后让待查找的数与中间位置的数比较,如果相等,则返回查找成功,如果不等,就确定待查找数的区间。
2、算法实现
public static int binarySearch(Integer[] srcArray, int des) {
int low = 0;
int high = srcArray.length - 1;
while ((low <= high) && (low <= srcArray.length - 1)
&& (high <= srcArray.length - 1)) {
int middle = low + ((high - low) >> 1);
if (des == srcArray[middle]) {
return middle;
} else if (des < srcArray[middle]) {
high = middle - 1;
} else {
low = middle + 1;
}
}
return -1;
}
- 描述折半查找的判定树
- 算法分析
ASL= 根据这半查找的判定树结点的比较次数
二叉排序树
- 二叉排序树(BST)的定义:
二叉排序树或者是一棵空树,要么满足:
1)如果它的左子树不空,则左子树所有结点的关键字都比跟结点的关键字小
2)如果它的右子树不空,则右子树所有结点的关键字都比跟结点的关键字大
3)左右子树又是一棵二叉排序树
这半查找算法对应的这半查找判定树实质上就是一棵二叉排序树,如果对二叉排序树进行中序遍历的话会得到一个有序序列 二叉排序树算法
二叉排序树将结点分为了两个部分,比根结点小的数据放到了左子树上,比根结点大的数据放到了右子树上。首先将待查找的数据与根结点计较,相等则返回指针,如果小于,则从左子树中查找,若大。则从右子树中查找二叉排序树关键字的插入
查找不成功的位置即为关键字的插入位置
voidInsertBST(t,key) {
if(t==NULL) {
t=(BTNode *)malloc(sizeof(BTNode));
t->lchild=t->rchild=NULL;
t->data=key;
return;
}
if(key<t->data)
InsertBST(t->lchild,key);
else
InsertBST(t->rchild,key);
}
- 二叉排序树的构造
不断插入关键字结点的过程
voidCreateBiTree(tree,d[],n) {
tree=NULL;
for(i=0;i<n;i++)
InsertBST(tree,d[i]);
}
- 删除关键字
左子树的最右端 + 左子树的最左端代替删除的结点
平衡二叉树
- 平衡二叉树概念
平衡二叉树是一种特殊的二叉树排序树,其中每棵子树的高度差绝对值不超过1。
引进平衡因子来判断一棵二叉排序树是否是平衡二叉树。结点的平衡因子 = 左子树高度- 右子树高度,取值范围为0, -1, 1。 - 平衡二叉树的建立
建立二叉排序树 + 平衡调整 - 平衡调整
1、最小数的概念:以距离插入结点最近,且平衡因子绝对值大于1的结点作为根的子树
2、调整过程:建立二叉树——确定平衡因子(3个结点)——调整
3、删除结点:左子树最右端——左子树最左端的结点代替
B-树
- B-树的定义
B是balanced的意思,B-树是一种平衡的多路查找树,在文件系统中很有用。
B-树的定义首先要引入一个B-树的阶的概念:B-树中所有结点的孩子结点个数最大值为B-树的阶,用m表示。
则一棵m阶的B-树定义为:要么是一棵空树,要么是满足一下性质的树:
1、每个结点最有有m个分支:根节点至少有两个分支,非根节点的话至少要有[m/2]向上取整个分支
2、结点中分支数 = 关键字树 + 1,且结点中的关键字都是按从小到大顺序排列的
3、B-树中下层结点的关键字位于上层节点关键字所划分的区间内。
4、B-树中叶结点都在同一层
所以总的来说:B-树是一棵特殊的平衡的多路查找出,他要求叶结点在同一层 - B-树结点的存储结构
n k1 k1 ... kn
p0 p1 p2 ... pn
n为关键字的个数、pi为指向孩子结点的指针
3. B-树的查找操作
因为B-树中下层结点的关键字位于上层节点关键字所划分的区间内,因此要根据区间来查找关键字
4. B-树的插入和删除P268
插入步骤:
1、确定每个结点关键字的个数范围:[m/2]-1~m-1(根结点可以只有两个分支,即一个关键字),
2、结点插入:满则拆分(中间位置拆分) + 合并 + 注意连锁反应
删除步骤
直接删除 + 借(左子树的最有段 + 左子树的最左端) + 合并(层数 - 1)