数据结构与算法之四 搜索算法

简介: 数据结构与算法之四 搜索算法

视频课堂https://edu.csdn.net/course/play/7621


目标


在本章中,你将学习: 使用线性搜索技术搜索数据和二叉搜索技术搜索数据


线性搜索:

是最简单的搜索方法, 也称作顺序搜索, 包括将用该条目逐一与列表中的条目进行比较, 线性搜索通过比较所需的元素与列表中第一个元素进行。

如果值不匹配:


      则所需的元素将与列表中的第二个元素作比较。

如果值还是不匹配:

    则所需的元素将与列表中的第三个元素作比较。

这个过程将一直持续下去,直到:

   找到所需的元素或到达列表的未尾为止。

使用线性搜索算法编写一个算法以搜索 员工记录列表 中给定的员工的工号:

1.  读取要搜索的工号     ( 首先确定你要找的工号 )

2. 设置 i = 0   n 是数组的最大值下标 ( 上界 )

3. 重复步骤 4 直到 i > n 或 arr[i] = employee ID

4. i 值增加 1

5. 如果 i > n:

          显示 “ 未找到 ”

    否则

          显示 “ 已找到 ”

搜索算法的效率是由算法的运行时间决定的。


在最佳情况下:

元素位于列表的第一个位置。

比较次数为 1 。

线性搜索的最佳的效率是 O(1) 。

在最差情况下:

元素 位于列表中最后一个位置或者它根本不存在于该列表中 。

比较次数为元素的数。

线性搜索最差的效率是 O(n) 。

在平均情况下:


线性搜索的平均比较数由最佳和最差搜索中的平均比较数决定 。

线性搜索的平均效率是 1/2(n + 1) 。

课间思考


您要在一个包含5000个元素的数组中应用线性搜索来搜索一个元素,如果在搜索的最后,您发现该元素不在该数组中,则为了在该给定的列表中搜索所需的元素您要进行多少次的比较?


答案:

5,000

问题描述:


编写一个在含有最多 20 个数的数组中使用线性搜索算法搜索一个给定数的程序, 如果要搜索的元素在列表中出现多次,则该程序应该显示第一次出现的位置,还 应该显示所作的比较总数。

二叉搜索算法:

用于搜索大列表, 以十分少的比较来搜索数据, 只要要搜索的列表已经排序,则可以使用二叉搜索算法

考虑一个示例。

您要在以字母顺序排列的电话目录中搜索名字 Steve 。

要使用二叉搜索算法搜索名字 Steve :

在中间打开电话目录以确定哪一半包含该名字。

在那一半的中间再打开以确定哪一半包含该名字。

重复此过程直到找到所需的名字为止。

二叉搜索每次就减少了一半的搜索页数。

编写一个算法以实现二叉搜索算法。

1. 接受要搜索的元素 ( 确定要查找的值 )

2. 设置 lowerbound = 0

3. 设置 upperbound = n – 1

4. 设置 mid = (lowerbound + upperbound)/2

5. 如果 arr[mid] = 所需元素:

a. 显示 “ 已找到 ”

b. 转到步骤 10

6. 如果所需元素 < arr[mid]:

a. 设置 upperbound = mid – 1

7. 如果所需元素 > arr[mid]:

a. 设置 lowerbound = mid + 1

8. 如果 lowerbound <= upperbound:

a. 转至步骤 4

9. 显示 “ 未找到 ”

10. 退出

在二叉搜索算法中的每个步骤中,搜索区域都减半。

该算法的最好情况是如果要搜索的元素正好位于列表的最中间的位置:

此情况的比较数为 1 。

在最差情况下,列表中未找到所需元素 :

在第一次对分后,搜索空间减少到 n/2 个元素,其中 n 是原始列表中的元素数。

第二次对分后,搜索空间减少到 n/4 ,即 n/22 个元素。

经过第 i 次对分后,搜索空间减少到 n/2i  元素。

课间思考

在 ___________ 搜索算法中,您从列表的一端开始并且扫描整个列表直到找到所需 项或到达列表的末尾为止。

答案:


线性

要执行 __________ 搜索算法,列表应该是经排序的。

答案:

二叉

问题描述:

编写一个程序,它使用二叉搜索在含有最多 20 个元素的数组中搜索一个数,假设 数组元素是以升序输入的。如果数组中有多个要搜索的数,则发现一个匹配后搜 索就停止了。程序还应该显示所作的比较总数。

小结

在本章中,你已经学到:

线性搜索的最佳效率是 O(1) ,最差效率 O(n) 。

要应用二叉搜索算法,应该确保要搜索的列表是排过序的。

二叉搜索的最佳效率是O(1),最差效率是O(log n)

/*从8个数中查找数字*/
using System;
class Ban
{
  public static void Main(string[]args)
  {
    //int []arr={8001,8002,8003,8004,8007,8010,8005,8009}; //定义有8个整数的数组   
    Console.WriteLine("请输入您的工号个数:");
    int n; //n为数组的上界
    n=Convert.ToInt32(Console.ReadLine());  //n就是数组的长度(个数)
    int []arr=new int[n];   //定义有10个数字的数组
    for(int j=0;j<n;j++)
    {
      Console.Write("请输入第"+(j+1).ToString()+"个数:");
      arr[j]=Convert.ToInt32(Console.ReadLine());
    }   
    //3.重复步骤 4 直到 i > n 或 arr[i] = id 才退出.
   char ch='y'; //定义我们不断查找的条件,如果为y|Y,则一直查找;n|N:则退出查找.
   while((ch=='y')||(ch=='Y'))
   {
    Console.WriteLine("请输入您要查找的数字:");
    int id=Convert.ToInt32(Console.ReadLine()); //定义要查找的数据元素  
    int lowerbound=0;
    int upperbound=n-1;
    int mid=(lowerbound+upperbound)/2;  //中间值下标
    //13   
    while(lowerbound<=upperbound) //实现找合适的中间值索引
    {
      if(id<arr[mid])
        upperbound=mid-1;
      else
        lowerbound=mid+1;
      mid=(lowerbound+upperbound)/2;  
      Console.WriteLine("low:"+lowerbound+"mid:"+mid+"upper:"+  upperbound);  
    }
    //针对找到数据元素,代码
        Console.WriteLine(arr[mid]);
    if(id==arr[mid])
        Console.WriteLine("ok");
    else    
      Console.WriteLine("没有找到....");
    Console.WriteLine("您是否继续查找,是(y|Y),否(n|N):");
    ch=Convert.ToChar(Console.ReadLine());  
  }//不断查找结束   
  }
}

/*使用二叉搜索在含有最多20个元素的数组中搜索一个数,假设数组是以升序输入的。如果数组中有多个要搜索的数,则发现一个匹配后搜索就停止了。
程序还应该显示所作的比较总数。
*/
using System;
class BinarySearch
{
  static void Main(string[]args)
  {
    int[]arr=new int[20]; //要搜索的数组
    int n;  //数组中的元素数
    int i;  //获取在数组中存储的元素数
    while(true)
    {
      Console.Write("请输入数组的元素个数:");
      string s=Console.ReadLine();
      n=Int32.Parse(s);
      if((n>0)&&(n<=20))
        break;
      else
        Console.WriteLine("\n数组最少1个元素,最多20个元素.\n"); 
    }
    //接受数组元素
    Console.WriteLine("------------------------------------------");
    Console.WriteLine("---------------输入数组元素---------------");
    Console.WriteLine("------------------------------------------");
    for(i=0;i<n;i++)
    {
        Console.Write("<"+(i+1)+">");
        string s1=Console.ReadLine();
        arr[i]=Int32.Parse(s1);
    }
    char ch='y';
    do
    {
      //要搜索的数
      Console.Write("请键入您要查找的数");     
      int item=Convert.ToInt32(Console.ReadLine());
      //应用二叉搜索
      int lowerbound=0;
      int upperbound=n-1;
      //获取中间元素的索引
      int mid=(lowerbound+upperbound)/2;
      int ctr=1;
      while((item!=arr[mid])&&(lowerbound<=upperbound)) //在数组中搜索元素的循环
      {
        if(item>arr[mid])
          lowerbound=mid+1;
        else
          upperbound=mid-1;
        mid=(lowerbound+upperbound)/2;
        //ctr++;
      }
      if(item==arr[mid])
        Console.Write("\n"+item.ToString()+"发现了位置:"+(mid+1).ToString());
      else
        Console.Write("\n"+item.ToString()+"在数组中没有发现");
        Console.Write("\n比较次数:"+ctr);
        Console.Write("\n继续搜索(y/n)");
        ch=char.Parse(Console.ReadLine());
    }while((ch=='y')||(ch=='Y'));
} 
}

/*
编写一个在含有20个数的数中使用线性搜索算法一个给定数的程序,如果要搜索的元素在列表中出现多次,则该程序应该显示第一次出现的位置,还应该显示所作
的比较总数。
*/
using System;
class SequentialSearch
{
  static void Main(string[]args)
  {
    int[]arr=new int[20]; //要搜索的数组
    int n;                //数组中的元素
    int i;  //获取在数组中存储的元素
    while(true)
    {
      Console.Write("请输入数组的元素个数:");
      string s=Console.ReadLine();
      n=Int32.Parse(s);
      if((n>0)&&(n<=20))
        break;
      else
        Console.WriteLine("\n数组最少1个元素,最多20个元素.\n"); 
    }
    //接受数组元素
    Console.WriteLine("------------------------------------------");
    Console.WriteLine("---------------输入数组元素---------------");
    Console.WriteLine("------------------------------------------");
    for(i=0;i<n;i++)
    {
        Console.Write("<"+(i+1)+">");
        string s1=Console.ReadLine();
        arr[i]=Int32.Parse(s1);
    }
    char ch='y';
    int  ctr;
    do
    {
      //接受要搜索的数
      Console.Write("\n请输入您要搜索的数:");
      int item=Convert.ToInt32(Console.ReadLine());
      //应用线性搜索
      ctr=0;
      for(i=0;i<n;i++)
      {
        ctr++;
        if(arr[i]==item)
        {
          Console.WriteLine("\n"+item.ToString()+"发现在位置"+(i+1).ToString());
          break;  
        } 
      }
      if(i==n)
      {
        Console.WriteLine("\n"+item.ToString()+"在数组中没有发现元素");
        Console.WriteLine("\n比较的次数为:"+ctr);
        Console.Write("\n继续搜索(y/n):");
        ch=Char.Parse(Console.ReadLine());  
      }
    }while((ch=='Y')||(ch=='y'));
  } 
}




目录
相关文章
|
2月前
|
机器学习/深度学习 算法 安全
【无人机三维路径规划】基于非支配排序的鲸鱼优化算法NSWOA与多目标螳螂搜索算法MOMSA求解无人机三维路径规划研究(Matlab代码实现)
【无人机三维路径规划】基于非支配排序的鲸鱼优化算法NSWOA与多目标螳螂搜索算法MOMSA求解无人机三维路径规划研究(Matlab代码实现)
188 5
|
2月前
|
机器学习/深度学习 算法 安全
【无人机三维路径规划】多目标螳螂搜索算法MOMSA与非支配排序的鲸鱼优化算法NSWOA求解无人机三维路径规划研究(Matlab代码实现)
【无人机三维路径规划】多目标螳螂搜索算法MOMSA与非支配排序的鲸鱼优化算法NSWOA求解无人机三维路径规划研究(Matlab代码实现)
152 0
|
1月前
|
算法 数据可视化 测试技术
HNSW算法实战:用分层图索引替换k-NN暴力搜索
HNSW是一种高效向量检索算法,通过分层图结构实现近似最近邻的对数时间搜索,显著降低查询延迟。相比暴力搜索,它在保持高召回率的同时,将性能提升数十倍,广泛应用于大规模RAG系统。
140 10
HNSW算法实战:用分层图索引替换k-NN暴力搜索
|
3月前
|
机器学习/深度学习 算法 文件存储
神经架构搜索NAS详解:三种核心算法原理与Python实战代码
神经架构搜索(NAS)正被广泛应用于大模型及语言/视觉模型设计,如LangVision-LoRA-NAS、Jet-Nemotron等。本文回顾NAS核心技术,解析其自动化设计原理,探讨强化学习、进化算法与梯度方法的应用与差异,揭示NAS在大模型时代的潜力与挑战。
882 6
神经架构搜索NAS详解:三种核心算法原理与Python实战代码
|
2月前
|
存储 算法 数据可视化
基于禁忌搜索算法的TSP问题最优路径搜索matlab仿真
本程序基于禁忌搜索算法解决旅行商问题(TSP),旨在寻找访问多个城市的最短路径。使用 MATLAB 2022A 编写,包含城市坐标生成、路径优化及结果可视化功能。通过禁忌列表、禁忌长度与藐视准则等机制,提升搜索效率与解的质量,适用于物流配送、路径规划等场景。
|
4月前
|
存储 监控 安全
企业上网监控系统中红黑树数据结构的 Python 算法实现与应用研究
企业上网监控系统需高效处理海量数据,传统数据结构存在性能瓶颈。红黑树通过自平衡机制,确保查找、插入、删除操作的时间复杂度稳定在 O(log n),适用于网络记录存储、设备信息维护及安全事件排序等场景。本文分析红黑树的理论基础、应用场景及 Python 实现,并探讨其在企业监控系统中的实践价值,提升系统性能与稳定性。
156 1
|
3月前
|
机器学习/深度学习 并行计算 算法
MATLAB实现利用禁忌搜索算法解决基站选址问题
MATLAB实现利用禁忌搜索算法解决基站选址问题
148 0
|
4月前
|
存储 搜索推荐 算法
加密算法、排序算法、字符串处理及搜索算法详解
本文涵盖四大类核心技术知识。加密算法部分介绍了对称加密(如 AES)、非对称加密(如 RSA)、哈希摘要(如 SHA-2)、签名算法的特点及密码存储方案(加盐、BCrypt 等)。 排序算法部分分类讲解了比较排序(冒泡、选择、插入、归并、快排、堆排序)和非比较排序(计数、桶、基数排序)的时间复杂度、适用场景及实现思路,强调混合排序的工业应用。 字符串处理部分包括字符串反转的双指针法,及项目中用正则进行表单校验、网页爬取、日志处理的实例。 搜索算法部分详解了二分查找的实现(双指针与中间索引计算)和回溯算法的概念(递归 + 剪枝),以 N 皇后问题为例说明回溯应用。内容全面覆盖算法原理与实践
182 0
|
4月前
|
存储 监控 算法
基于跳表数据结构的企业局域网监控异常连接实时检测 C++ 算法研究
跳表(Skip List)是一种基于概率的数据结构,适用于企业局域网监控中海量连接记录的高效处理。其通过多层索引机制实现快速查找、插入和删除操作,时间复杂度为 $O(\log n)$,优于链表和平衡树。跳表在异常连接识别、黑名单管理和历史记录溯源等场景中表现出色,具备实现简单、支持范围查询等优势,是企业网络监控中动态数据管理的理想选择。
150 0
|
5月前
|
机器学习/深度学习 算法 数据可视化
基于Qlearning强化学习的机器人迷宫路线搜索算法matlab仿真
本内容展示了基于Q-learning算法的机器人迷宫路径搜索仿真及其实现过程。通过Matlab2022a进行仿真,结果以图形形式呈现,无水印(附图1-4)。算法理论部分介绍了Q-learning的核心概念,包括智能体、环境、状态、动作和奖励,以及Q表的构建与更新方法。具体实现中,将迷宫抽象为二维网格世界,定义起点和终点,利用Q-learning训练机器人找到最优路径。核心程序代码实现了多轮训练、累计奖励值与Q值的可视化,并展示了机器人从起点到终点的路径规划过程。
236 0

热门文章

最新文章