查找算法集合

基本概念

查找表:有同一类型的数据元素构成的集合,数据元素间存在着松散的关系,没有严格的前驱后继关系。
查找:根据给定值在查找表中确定一个其关键字等于给定值的数据元素
关键字:用来标识一个数据元素的某个数据项的值
查找的成功:关键字等于给定的元素

查找的操作: 存在性确定,检索属性,插入元素,删除元素
查找表的分类:静态查找表,动态查找表
评价指标:平均查找长度ASL

研究内容:查找表的组织方式以及如何提高查找效率

线性表的查找

顺序查找(线性查找)

线性表上的静态查找,表内元素可无序

struct SSTable{
	int *arr;
	int len;
}

在顺序表中查找值为key的数据元素
算法:

//查找成功返回下标,失败返回0,表头作为哨兵
int Search_Seq(SSTable ST,int key){
	ST.arr[0] = key;
	int i;
	for(i = ST.len;ST.arr[i] != key;i--) ;		
	return i;
}

比较次数:n-i+1,查找失败查找n+1次
ASL:(n+1)/2
时间复杂度:n
空间复杂度:1

如何提高查找效率:

  1. 被查找概率高的放前面
  2. 俺查找概率动态调整顺序:每个结论中加入访问频度域,俺非递增排列,每次查很早后均将刚查到的记录移至表头

优点:算法简单,逻辑次序存储结构无要求
缺点:时间效率低

折半查找(二分查找)

每次讲带查找记录所在区间缩小一半
mid = (left + right) / 2
key < mid:right = mid - 1
key > mid:left = mid + 1
key = mid:找到
right < left:结束
算法(非递归):

int Search_Bin(SSTable ST,int key){[
	int left = 1,right = n,mid = (left + right) / 2;
	while(l <= r){
		mid = l + r / 2;
		if(ST.arr[mid] == key)return mid;
		else if (key < ST.arr[i]) r = mid - 1;
		else  l = mid + 1;
	}
	return 0;
}

递归算法:

int Search_Bin(SSTable ST,int key,int l,int r){
	if(l > r)return 0;
	mid = (l + r) / 2;
	if(key == ST.arr[mid]) return mid;
	else if (key < ST.arr[mid])Search_Bin(ST,key,l,mid - 1);
	else Search_Bin(ST,key,mid + 1,r);
}

判定树:
比较次数 = 路径上的节点数 = 节点的层数 <= 树的深度 = log2^n + 1
在这里插入图片描述
ASL = (n + 1) / n log2^(n+1) - 1
约等于log2^(n+1) - 1 (n>50)
时间复杂度:lgn
优点:效率比顺序查找高
缺点:只适用于有序表,且限于顺序存储结构

分块查找(索引顺序表查找)

条件:表中分成若干块,分块有序,块内可无序
查找过程:先确定所在块,再在块内查找
n个元素,s块
ASL = log 2(n/s+1) + s/2
快于顺序查找,略慢与二分查找
优点:插入删除较容易
缺点:增加索引表所需空间
适用情况:线性表要快速查找还要动态变化

查找方法的比较

在这里插入图片描述

树表的查找

表的插入删除操作频繁,为维护表的有序性,改用动态查找表——特殊的树
表结构在查找过程中动态生成

二叉排序树

性质:

  1. 若左子树非空,则左子树上所有节点的值均小于根节点的值
  2. 若右子树非空,则右子树上所欲节点的值均大于等于根节点的值
  3. 其左右子树本身是一颗二叉排序树
查找
struct BSTNode{
	int data;
	BSTNode *l,*r;
}

算法思想:
若二叉排序树为空,查找失败,返回空指针;
若二叉排序树非空,讲key与根节点的值相比较:
==,查找成功,返回根节点地址;
《,找左子树
》,找右子树

BSTree SearchBST(BSTree T,int key){
	if( !T || key == T->data) return T;
	else if(key < T->data) return Search BST(T->l,key);
	else return SearchBST(T->r,key);
}

查找分析:
含有n个节点的二叉排序树的平均查找长度和树的形态有关
完全二叉树:log2^n
单支二叉树:n

如何提高查找效率:平衡化处理

插入

若二叉排序树为空,则插入节点作为根节点插入空树中
否则,继续在左右子树上查找
树中有,不再插入
树中没有,查找直到某叶子节点的左子树或右子树为空为止,则插入节点为其孩子节点

生成

从空树除法,经过一系列的查找、插入操作之后,生成一颗二叉排序树
关键字输入顺序不同,生成的二叉排序树不同

删除

不饿能把以该节点为根的子树都删去,删除后二叉树仍然满足二叉排序树

  1. 删除叶子节点:直接删,其父节点的子节点为空
  2. 只有左子树或右子树:用其左子树或右子树替换他
  3. 左右子树都有:前驱节点(左子树中最大的节点)代替他,前驱节点原位置删除;后继节点代替(右子树中最小的节点)
    注意:可以减小树的高度的优先
平衡二叉树(AVL)

是空树或者有下列性质的二叉排序树:

  1. 左子树与右子树的高度差的绝对值小于等于1
  2. 左子树和右子树也是平衡二叉排序树

平衡因子(BF) = 节点左子树高度-节点右子树高度

构造
失衡二叉排序树的分析与调整

在平衡二叉树中查如一个系欸但时,可能导致失衡,即出现平衡因子绝对值大于1的节点,必须重新调整树的结构使之回复平衡。

平衡调整:
失衡的节点不止一个:找最小失衡子树的根节点
调整原则:降低高度;保持二叉排序性质

从上到下分别是ABC
LL型:
B节点的左子树上升,A节点成为B节点的右孩子,原来b节点的右子树作为A的左子树
RR型:
B节点带右子树一起上升,A成为B的左孩子,原B节点的左子树作为A的右子树
LR型:
C上升,B成为C的左孩子,A成为C的右孩子,C原来的左子树变为B的右子树,C原来的右子树变为A的左子树
RL型:
C上升,A成为C的左孩子,B成为C的右孩子,C原来的左子树成为A的右子树,C原来的右子树成为B的左子树

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值