数据结构 C7 查找(上)

简介: 数据结构 C7 查找

7.1查找的基本概念


查找:在数据集合上寻找满足某种条件的数据元素的过程称之为查找
查找表(查找结果):用于查找的数据集合称为查找表,它由同一类型的数据元素(或记录)组成
关键字:数据结构中唯一标识该元素的某个数据项的值,使用基于关键字的查找,查找结果应该是唯一的。


也就是说你查到哪个数据结构,那么这个数据结构记忆是你的查找表。关键字是唯一的,需要可区分性,唯一性;

如看下图:

1670676547280.jpg

1670676554373.jpg


对查找表的常见操作

1.查找符合条件的数据元素

2.插入 删除某个数据元素

只需要进行操作1的是静态查找表。两者都要进行操作的是动态查找表

如下图:


1670676560839.jpg


评价指标

查找长度–在查找运算中,需要对比的关键词的次数称之为查找长度

平均查找长度(ASL)–所有查找过程中进行关键字的比较次数的平均值

公式如下:

1670676571464.jpg

举个例子:二叉排序树的成功/失败的ASL

1670676581836.jpg

1670676589210.jpg


ASL的数量级反应了查找算法的时间复杂度.


7.2顺序查找和折半查找


7.2.1顺序查找


顺序查找,又叫线性查找,通常用于线性表

算法思想:

从头到脚挨个查找(或者反过来欸个查找)

如下图:查找43,逆从头开始到尾部查找就行或者反过来


1670676612858.jpg


代码实现

查找成功:

1670676622915.jpg

查找失败:

1670676629506.jpg

typedef struct{
  elemtype *elem;
  int tablelen;
}SStable;
int search_seq(sstable ST,elemtype key){
  int i;
  for(i=0;i<ST.Tablelen&&ST.elem[i]!=key;++i);
  return i==ST.TableLen?-1:i;
}


类似算法 :哨兵算法


查找成功:

1670676648040.jpg


查找失败:

1670676658513.jpg


typedef struct{
 elemtype *elem;
 int tablelen;
}SStable;
int search_seq(sstable ST,elemtype key){
ST.elem[0]=key;
 int i;
 for(i=ST.Tablelen;ST.elem[i]!=key;--i);
 return i;
}

1670676673395.jpg

查找效率分析


1670676683988.jpg


基于这个算法的效率,这个算法是否可以优化呢?

对表进行有序排列,再进行查找,如下图:

1670676692203.jpg

由此引申了查找判定树,上图的查找判定树如下


1670676700562.jpg

1670676706470.jpg


另外一种优化方法:当你的每一个结点的查找概率不一样的时候,按照概率由大到小排序。

这样成功的几率会增大。

1670676722302.jpg


7.2.2折半查找


折半查找,又称之为二分查找,仅仅适用于有序的顺序表。


算法思想

设置两个指针,分别指向数组的头部与数组的尾部,在设置一个指针指向前两者除以二取整的地方。

然后三个指针分别指向了最大值,最小值,中间值。然后拿现在查找的数字和中间值比较,如果大于只能在右边,设置low=mid+1;如果小于,只能在左边,设置high=mid-1;

重复上面过程直到查找成功low=high=mid=该查找的数值。

如果low=high还没有查找成功,那么下面就会变成low>high,查找失败.

具体过程如下图。

1670676770088.jpg

1670676777491.jpg

1670676783464.jpg

1670676795508.jpg

上面的例子是查找成功的例子,那咱们看一看一个查找失败的例子;

1670676805219.jpg

1670676813099.jpg

1670676820272.jpg

1670676827081.jpg

1670676836523.jpg

以上就是算法的基本思想。


算法实现

代码实现:

typedef struct{
  elemtype *elem;//顺序表拥有随机访问的特性,链表没有
  int tablelen;
}sstable;
int binary_search(sstable l,elemtype key){
  int low=0,high=l.tablelen-1,mid;
  while(low<=high){
  mid=(low+high)/2;
  if(l.elem[mid]==key)
    return mid;
  else if(l.elem[mid]>key)
    high=mid-1;
  else 
    low=mid+1;
  }
  return -1;
}


折半查找判定树

如果当前low和high之间有奇数个元素,则mid分隔后,左右两部分元素个数相等

1670676895051.jpg

1670676903060.jpg

如果当前Low和high之间有偶数个元素,则mid分隔后,左半部分比右半部分少一个元素

1670676912206.jpg

1670676920250.jpg

这样的话就有这么一个规律:如下

1670676927863.jpg

做个练习按照上面的规律:画出对应的折半查找判定树:

1670676952345.jpg

由以上发现:折半查找判定树一定是个平衡二叉树

1670676959688.jpg

1670676966326.jpg

折半查找效率

直接举个例子:如下

1670676974584.jpg


对于查找成功的例子,对于上图一共要进行四轮查找。对于失败则最多要五轮


对应的成功失败的查找效率如下图。

1670676982956.jpg

1670676996223.jpg

1670677002551.jpg

1670677010574.jpg


相关文章
|
存储 算法 C语言
数据结构第十一周笔记—— 散列查找 (慕课浙大版本--XiaoYu)(二)
数据结构第十一周笔记—— 散列查找 (慕课浙大版本--XiaoYu)(二)
93 0
|
存储 算法 C语言
数据结构第十一周笔记—— 散列查找 (慕课浙大版本--XiaoYu)(一)
数据结构第十一周笔记—— 散列查找 (慕课浙大版本--XiaoYu)(一)
109 0
|
存储 索引
|
算法 索引
|
存储 C语言 C++
数据结构 动态查找与二叉排序树
数据结构 动态查找与二叉排序树
69 0
浙大版《数据结构学习与实验指导(第2版)》案例5-1.1:线性探测法的查找函数
浙大版《数据结构学习与实验指导(第2版)》案例5-1.1:线性探测法的查找函数
295 0
|
存储 算法 Java
数据结构之查找和排序
1.2 查找树 1.2.1 二叉查找/搜索/排序树 BST (1)或者是一棵空树 (2)或者是具有下列性质的二叉树 ①若它的左子树不为空,则左子树上所有结点的值均小于它的根结点的值 ②若它的右子树上所有结点的值均大于它的根结点的值 ③它的左、右子树也分别为二叉排序树
数据结构之查找和排序
|
存储 算法
数据结构 第七章 查找
数据结构 第七章 查找
76 0
数据结构 第七章 查找