查找算法总结

@skiery

[总结自王道视频,希望对大家找工作有所帮助]

查找

定义:在数据集合中寻找满足某些条件的数据元素过程。

0.1查找表

用于查找的数据集合成查找表:
1.查询某个元素是否存在;
2.查询某个元素的属性;
1 2属于静态查找表,常用方式:顺序查找表、折半查找
3.动态查找表:二叉排序树、二叉平衡树

0.2关键字

数据元素中某个可以唯一标识该元素的数据项;

0.3平均查找长度(ASL)

在查找过程中,一次查找的长度指需要比较的关键字的次数,而平均查找长度是所有查找过程中进行关键字的比较次数的平均值。
ASL = ΣPi*Ci n为查找表中元素个数,Pi是查找第i个元素的概率,一般为等概率查找,Pi的为1/n,Ci为找到第i个元素需要比较的关键字次数,即查找长度。

1.1顺序查找

主要用于在线性表中进行查找,从查找表的一端开始,顺序扫描查找表,依次将扫描到的关键字和带查找的值key进行比较,相等成功,扫描结束未发现元素,查找失败。

int search1(int A[],int n,int key){
	for(int i=0;i<n;i++){
		if(A[i] == key){
			return i+1;
		}
	}
	return 0;
}

int search2(int A[],int n,int key){
	if(A[0]==key){
	return 1;
	}
	A[0] = key;
	while(A[i]!=key){
	i--;
	}
	if(i==0) return 0;
	return i+1;
}

ASL:
1.成功:(n+1)/2
2.失败:n
时间复杂度:O(n)

1.2折半查找

算法思路:首现给定key与表中间元素的关键字比较,相等则查找成功,返回位置;失败则缩小查找范围,在缩小的范围内继续进行折半查找,重复直到找到位置,或确定没有该元素,查找失败。
适用范围:有序的顺序表

int Binary_Search(int A[],int n,int key){
	int low = 0;int high = n-1;int mid;
	while(low<=high){
	mid = (low+high)/2;
	if(A[mid] == key){
			return mid+1;
		}
	else{
		if(A[mid]>key) high = mid-1;
		else low = mid+1;
			}
		}
	return 0;
}

折半查找判定树:可以将查找过程化为折半查找二叉树,查找的比较次数就是从根节点到该节点经历的结点数
N个结点的完全二叉树高度为log(2(N+1)),所以折半查找时间复杂度为O(logN)。
ASL:成功:直接求所有比较成功次数的期望,即每个点所在层数的和除以总点数;
失败:直接求在每个位置失败所需的次数,再除以失败的情况的和,得到结果。

1.3分块查找

按索引查找,需要额外建立一个索引表来存储索引,每个索引对应表中每一块,并且每个块间都是有顺序的。

(1)块间折半查找,块内顺序查找
ASL = ASL(折半)+ASL(顺序) = [log2(b+1)] + (1+s)/2
(2)块间块内均顺序查找:
ASL = ASL(块间顺序)+ASL(块内顺序) = (1+b)/2 + (1+s)/2

2.1二叉排序树

二叉排序树(Binary Search Tree),也叫二叉搜索树,是一颗空树,或者具有以下性质的树:
(1)若左子树不空,则左子树上所有结点值均小于其根结点的值;
(2)若右子树不空,则右子树上所有结点值均大于其根结点的值。
左小右大
与根结点比较,小于根结点向左子树找,大于根结点向右子树查找。

2.1.1查找关键字

BitNode *BST_Search(BitNode *t,int key)){
	if(t==NULL) return NULL;
	else{
	if(t->key==key) return t;
	else if(key<t->key)return BST_Search(t->lchild,key);
	else return BST_Search(t->rchild,key);
	}
}

2.1.2插入关键字

1)空树:直接插入;
2)树非空:检测是否有重复关键字结点;
1.存在:不插入,直接返回插入失败;
2.不存在:检查根结点值和待插入关键字值的大小关系递归插入左右子树

int BST_Insert(BitNode* &t,int k){
	if(t==NULL){
	t = (BitNode*)malloc(sizeof(BitNode));
	t->key = k;
	t->lchild = t-rchild = NULL;
	return 1;
	}
	else if(t->key == k) return 0;
	else if(t->key>k) return BST_Insert(t->lchild,k);
	else return BST_Insert(t->rchild,k);
}

2.1.3删除关键字

1.删除叶子节点:直接删除;
2.只有一个孩子节点:用孩子节点替代父节点;
3.有两个子节点:找到左子树的最大节点作为前驱节点;找到右子树的最小节点作为后继节点,

散列表

散列表:根据给定的关键字计算出关键字在表中的地址的数据结构,建立了关键字和存贮地址之间的一种直接映射关系。
散列函数:一个把查找表中的关键字映射成为该关键字对应的地址的函数,几位Hash(key)=Addr

会用即可,这里面试和应用不会这么详细,有兴趣大家自己看吧~

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值