博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
数据结构学习笔记之查找基本概念与线性结构的查找算法
阅读量:3934 次
发布时间:2019-05-23

本文共 2678 字,大约阅读时间需要 8 分钟。

查找基本概念与线性结构的查找算法

一、基本概念

1、查找的定义

  • 在数据集合中寻找满足所给条件的数据元素的过程,称之为查找;查找的结果有且只有两种:成功和失败,换句话就是:要么从集合中找到至少一个满足条件的元素,要么在集合一个也找不到满足条件的元素

2、查找表

  • 也叫做查找结构
  • 待进行查找的数据集合称为查找表,其数据元素的类型往往是一样的,可以是数组或链表等。对链表进行的操作一般有:
    确定某个值是否在查找表中
    从查找表中筛选出满足特定条件的元素的各种属性
    从查找表中确定一个用于进行元素插入操作的位置
    从查找表中寻找满足删除条件的元素进行删除操作

3、静态查找表与动态查找表

  • 当一个查找表的所有操作,只涉及到元素确定,也即是上面的 ①②,那么这种查找表就称为静态查找表。适合静态查找表的查找算法有:顺序查找、折半查找和散列查找
  • 相反的,当一个查找表的全部操作涉及元素修改,即上面的 ③④,那么这种查找表就称之为动态查找表;适合动态查找表的查找算法有:二叉排序树查找、散列查找等

4、关键字与平均查找长度

  • 关键字,是指数据元素中能够唯一标识该数据元素的数据项的值,例如学生信息表中的学号就是一个具体的学生信息的关键字;基于关键字的查找,其查找成功的结果往往是唯一确定的。
  • 在查找过程中,一次查找的长度指需要比较的关键字的次数,平均查找长度则是指整个查找过程中进行关键字比较的次数的平均值
    在这里插入图片描述
  • Pi 是第 i 个数据元素的概率,一般认为查找表中的元素是等概率的,即表长的倒数;
  • Ci 是第 i 个数据元素所需进行的比较次数。
  • 平均查找长度,往往用于衡量一个算法是否高效。

二、针对线性结构的查找算法

  • 针对线性结构的查找算法,也是诸多查找算法中较为容易实现的算法,有顺序查找、折半查找和分块查找

1、顺序查找

  • 也称为线性查找,分为对一般无序线性表的顺序查找和针对关键字有序的顺序表进行查找。

1.1、一般线性表的顺序查找

  • 这是最为简单的查找,其思想就是从表的一端按下标依次比较直到表尾,若找到则返回元素下标,否则返回查找失败,代码如下:
int SimpleSeqSearch(int arr[], int len, int keyValue){
for(int i=0;i
  • 此外,还有一种使用哨兵的实现,如下:
int SeqSearch(int arr[], int len, int keyValue){
arr[0] = keyValue; // 哨兵, 此时的数组是从下标 1 开始赋值的,即参数数组的下标 0是空 int i; for(i=len; arr[i]!=keyValue; i--); return i;}
  • 引入“哨兵” 的目的减少不必要的判断语句,从而提高程序运行效率。
  • 付于有 n 个元素的表,给定值key与表中第i个元素相等,即定位第i个元素时,需进行n-i+1次关键字的比较,即Ci=nーi+1.査找成功时,顺序查找的平均长度为:
    在这里插入图片描述
  • 而对于等概率的情况下:
    在这里插入图片描述
  • 而查找不成功的平均查找长度为 n+1.
  • 实际中,遇到的查找表的往往不是等概率,此时可以使表中的元素按查找概率从小到大进行排序。
  • 这种简单顺序查找的优点是对数据元素的存储没有要求,缺点是当规模很大时,平均查找长度很大,效率低下。

1.2、有序表的顺序查找

  • 对已经排好顺序的查找表进行查找时,可不必从头到尾进行判断了,因为表中某个两个连续元素是满足:前者小于等于目标值,后者大于目标值;或者反过来。当取不到等号时,便可以判断目标值在查找表中不存在;这段描述可以用如下图的判定树来表示:
    在这里插入图片描述
  • 此时查找不成功在等概率的情形下的平均查找长度为:
    在这里插入图片描述
  • qj 表示到达第 j 个失败节点的概率,等概率情形下就是 1/(n+1);lj 表示第 j 个失败节点所在的层数。以上面的例子,即 n=6 的情形,查找失败的平均查找长度为 6/2+6/7=3.86,显然比第一种顺序查找算法的好一些。
  • 实现代码如下:
    int OrderSearch(int arr[], int len, int keyValue){
    for(int i=0; i
    keyvalue) return -1; }}

2、折半查找

  • 二分查找
  • 算法基本思想如下:
    1)首先将给定值keyvalue与序列中间位置的元素进行比较,若相等,则查找成功,返回序列下标;
    2)若不等,则在中间元素意外的前半部分或后半部分查找,并在前半部分或后半部分同样用二分法查找;
    3)重复上述操作直到找到或确定表中没有要查找的元素。
  • 具体是在前半部分循环还是后半部分循环,只要看序列是增序排列还降序排列,所以说,折半查找是针对有序序列的查找算法
  • 算法实现代码如下:
    // 二分查找,针对有序序列的查找算法int BinSearch(int arr[], int len, int keyValue){
    int low = 0, high = len - 1, mid; while (low <= high) {
    mid = (low + high) / 2; if (arr[mid] == keyValue) return mid; else if (arr[mid] > keyValue) high = mid - 1; else low = mid + 1; } return -1;}
  • 二分查找的判定树是一棵平衡二叉树,故而在等概率下,查找成功的平均长度为:
    在这里插入图片描述
  • 而时间复杂度为:O(log2n),比顺序查找效率高。

3、分块查找

  • 分块查找又称为索引查找,吸取了顺序查找和折半查找各自的优点,既有动态结构,又适于快速查找
  • 该算法的基本思想如下:
    ① 先将查找表划分为若干子块,块内可以无序,块间有序,即第一块的最大关键字小于第二块中所有的关键字,以此类推;
    ② 建立一个索引表,索引表中的每个元素含有各块的最大关键字和各块的第一个元素的地址,索引表按关键字有序排列。
    ③ 先确定待查关键字所在的块,然后再在块内进行搜索。
  • 一般分块时都是等长划分,子块该多长视查找表的规模而定,但是总的来说不宜太长,太长便不能彰显分块查找的优势,也不能太短,子块太短会导致索引表过长。在子块数目为 b,块长为 s 与等查找概率的情况下,平均查找长度为:
    在这里插入图片描述
  • LI是索引查找的平均查找长度,Ls是块内查找平均查找长度。

转载地址:http://khqgn.baihongyu.com/

你可能感兴趣的文章
电商系统的高并发设计和挑战
查看>>
【深入Java虚拟机】之二:Class类文件结构
查看>>
【深入Java虚拟机】之三:类初始化
查看>>
对齐数导致的错误
查看>>
thrift 实战总结
查看>>
event_base
查看>>
BufferEvent
查看>>
Evbuffer
查看>>
gcc / g++ Debug 模式
查看>>
c99:Designated Initializers(指定初始化)
查看>>
getopt函数
查看>>
线程中join()和detach()的区别
查看>>
16.让对话框支持拖拽操作/目录框打开操作
查看>>
电影天堂爬虫
查看>>
sql练习--查找所有已经分配部门的员工的last_name和first_name
查看>>
sql练习--查找所有员工的last_name和first_name以及对应部门编号dept_no,也包括展示没有分配具体部门的员工
查看>>
sql练习--查找所有员工的last_name和first_name以及对应的dept_name,也包括暂时没有分配部门的员工
查看>>
Transformer-based Object Re-Identification论文解读
查看>>
Android BLE开发
查看>>
Java内部类详解
查看>>