数据结构与算法知识点——查找算法

概念

  • 查找表:同一类型的数据元素构成的集合
  • 操作:查询/检索/插入/删除
  • 查找速度——平均查找长度ASL

静态查找表

顺序查找表

  • 组织方式:线性表
  • 查找方法:从表的一端顺序找到另一端
  • 存储结构/元素顺序均无要求

算法实现

define max 100;
typedef struct{
  keytype key;
}elemtype;
typedef struct{
  elemtype elem[max];
  int length;
}SqList;
SqList L;

int search(SqList L,keytype x)
{
  int i;
  for(i=0;i<L.length;i++)
  	if(L.elem[i].key==x)return i+1;
  return 0;
  
  //加入哨兵项
  '''
    int k=L.length;
  L.elem[0].key=x;	//低端/高端均可
  while(x!=L.elem[k].key)
    k--;
  return k;'''
}

ASL分析(每个元素查找成功的概率相同)

  • 查找成功的ASL=(n+1)/2
  • 查找一次平均检索长度的ASL=3(n+1)/4
    • 查找一次成功和失败的概率相同

有序查找表(二分查找表)

  • 查找表组织有序(递增或递减),顺序存储

  • 二分查找可以用二分查找判定树表示外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

    算法分析

    1. 关键字排序时间复杂度为: O(nlogn)
    2. 二分查找只适用顺序存储结构(不便于插入和删除),适用于一经建立就很少改动而又经常需要查找的线性表
    3. 查找少而改动多的情况,适合采用链表进行顺序查找;链表无法实现二分查找

    算法实现

    int binaryS(SqList L, KeyType x)
    { int low=0, high=L.length-1, m;
    	while(low<=high)
    	{ m=(low+high)/2;
    		if(L.elem[m].key==x) return m+1;
    		if(L.elem[m].key>x) high=m-1;
    		else low=m+1;
    	} 
     	return 0;
    }
    

    ASL分析

    • 查找成功时ASL近似等于 log(n+1) - 1
    • 查找失败时所需比较的关键字个数不超过(<=)判定树的深度,最坏的情况下比较次数为 log2(n) + 1

索引顺序表(不是很懂)

策略(还需要理解)?????

  • 对索引表采用二分查找或顺序查找,确定待查记录所在的块
  • 在线性表查找k,诺其在线性表存在,且位于第 i 块,那么一定有:第 i-1块的最大键值 < k <= 第i块的最大键值
  • 然后再相应的块中进行顺序查找

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

动态查找表

二叉排序树和平衡二叉树

二叉排序树

定义

  • 左子树所有结点均小于根节点
  • 右子树所有结点均大于根节点
  • 左右子树都是二叉排序树

要点

  • 二叉排序树中序遍历结果递增有序(可用于判断一颗二叉树是否为二叉排序树)
  • 可以将无序序列变有序
  • 同一组数据,输入顺序不同,所建立的二叉排序树不同

查找 x 过程

  1. 二叉树为空,失败
  2. 否则,x 与根节点比较:相等,查找成功结束;否则,
    1. x 小于根节点,在左子树上继续执行 1
    2. x 大于根节点,在右子树上继续执行 1

查找算法实现

//二叉链表作为二叉排序树的存储结构
typedef struct NODE
{
  int key;
  struct NODE *lc,*rc;
}BiNode,*BiTree;

//二叉排序树的检索算法
BiTree Search(BiNode *t,int x)
{
  BiTree p=t;
  while(p!=p->key)
  {
    if(x<p->key) p=p->lc;
    else p=p->rc;
  }
  return p;
}

ASL分析(重要)

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

插入算法实现(需要理解)

​ 新插入的结点一定是作为叶子结点添加上

int Insert(Bitree &t,int x)//二叉排序树的插入算法
{ BiTree q, p, s;
	q=NULL; p=t; ;//p为正在查看的节点,初始从根节点开始;q为p的双亲节点,根节点无双亲节点
	while(p!=NULL)
	{ if (x==p->key) return 0;//在当前的二叉排序树中找到x,直接返回,不再做插入
		q=p;
		if (x<p->key) p=p->lc;
		else p=p->rc;
	}
	s=(BiTree)malloc(sizeof(Binode)) ;//没找到x,做插入:先申请节点空间
	s->key=x;s->lc=NULL; s->rc=NULL ;//存放x,设为叶节点
	if (q==NULL)t=s; ;//若原先的二叉树是一棵空树,新插入的x对应的节点s为插入	后二叉树的根节点
	else if (x<q->key) q->lc=s; ;//插入s为q的孩子
	else q->rc=s; return 1;
}

删除算法实现

实现策略:p 为待删除结点

  • p 为叶节点,只管删除即可
  • p 只有左子树或只有右子树,将plpr替换被删结点p
  • p 左右子树均有,按照中序遍历保持有序
    • 用 pl 上的最大值 Smax 替换 p, 在删除 p 或者
    • 用 pr 上的最小值 Smin 替换 p, 再删除 p

最佳二叉排序树

  • 前边提到,不同输入顺序建立的二叉排序树不同,称其中平均查找性能最高的为最佳二叉排序树
  • 按照二分查找判定树的建立过程建立的二排序树为最佳二叉排序树(还需要理解)
  • 二叉排序树的查找速度一般比顺序查找块,但如果是单支树一样快

平衡二叉树(AVL树)

注:我们希望建立的二叉排序树均为平衡二叉树

  • 空树,或每个结点的平衡因子 BF 不超过1
  • **结点的平衡因子 BF ** :结点左子树的深度-右子树深度

构造平衡二叉树

插入过程中采用平衡旋转法

  • LL平衡旋转:单向右旋(指针指向的改变)
    • A的左孩子B右旋成为新的根结点
    • A右旋成为B的右孩子
    • B的原右孩子成为A的左孩子·
  • RR平衡旋转:单向左旋
  • LR平衡旋转:先左后右 (左子树左旋)
  • RL平衡旋转:先右后左

旋转操作特点

  1. 对不平衡的最小子树操作
  2. 旋转后子树根节点平衡因子为 0
  3. 旋转后子树深度不变故不影响全树,也不影响插入路径上所有祖先结点的平衡度

性能分析(记忆)

平衡树查找的时间复杂度为 O(log n)

查找和二叉排序树一致,比较的次数不超过平衡二叉树的深度

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

B-树和B+树(自学)

哈希表

哈希函数:关键字的值和存储位置的对应关系

同义词:发生冲突的两个数据称为同义词

哈希函数构造方法

直接定址法

数字分析法

适用于:能预先估计出全体关键字的每一位上各种数字出现的频度

平方取中法

取平方,扩大差距

除留余数法

随机数法

处理冲突的方法

为产生冲突的地址寻找下一个哈希地址

(理想是通过关键字,不进行比较直接得到存放位置,但是由于冲突的存在还是要进行比较,知识比较的次数变少了)

开放定址法

设定一截探测序列,为发生冲突的数据寻找存放位置

  • 线性探测:冲突顺序往后看

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

  • 平方(二次)探测再散列: +1,-1,+4,-4…
  • 随机探测再散列

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

增量d应具备完备性:

  • 产生h均不相同,且遂产生m-1个h值能覆盖哈希表中所有地址
  • 平方探测时表长m必须形如4*j+1的素数
  • 随机探测时m和d没有公因子

再哈希法

链地址法

将所有哈希地址相同的数据(同义词)都链接在同一链表中

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

建立一个公共溢出区

哈希表查找分析

ASL:平均查找次数 决定因素

  • 选用的哈希函数
  • 选用的处理冲突的方法
  • 哈希表饱和的程度,装载因子 α =n/m的大小(n—数据数,m—表的长度)

结论

  1. 哈希表的ASL是α的函数,而不是n的函数
  2. 哈希表构造查找表时可以选择一个适当的装填因子,使得平均查找长度限定在某个范围内

哈希表删除分析

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

开放地址法

删除一个数据后为保证查找工作的正常进行不能真删除,需要添加删除标志,删除时只添加删除标记
决定因素

  • 选用的哈希函数
  • 选用的处理冲突的方法
  • 哈希表饱和的程度,装载因子 α =n/m的大小(n—数据数,m—表的长度)

结论

  1. 哈希表的ASL是α的函数,而不是n的函数
  2. 哈希表构造查找表时可以选择一个适当的装填因子,使得平均查找长度限定在某个范围内

哈希表删除分析

[外链图片转存中…(img-k41x78kc-1717853081538)]

开放地址法

删除一个数据后为保证查找工作的正常进行不能真删除,需要添加删除标志,删除时只添加删除标记

  • 22
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值