c 语言 三元搜索 - 迭代与递归(Ternary Search)

        计算机系统使用不同的方法来查找特定数据。有多种搜索算法,每种算法更适合特定情况。例如,二分搜索将信息分为两部分,而三元搜索则执行相同的操作,但分为三个相等的部分。值得注意的是,三元搜索仅对排序数据有效。在本文中,我们将揭开三元搜索的秘密——它是如何工作的,为什么它在某些情况下更快。无论您是编码专家还是刚刚起步,都准备好快速进入三元搜索的世界!
什么是三元搜索?
        三元搜索是一种搜索算法,用于查找排序数组中目标值的位置。它的工作原理是将数组分为三部分,而不是像二分搜索那样分为两部分。基本思想是通过将目标值与将数组分为三个相等部分的两个点上的元素进行比较来缩小搜索空间。
        mid1 = l + (rl)/3 
        mid2 = r – (rl)/3 
三元搜索的工作原理:
        这个概念涉及将数组分成三个相等的段,并确定关键元素(正在寻找的元素)位于哪个段。它的工作原理与二分搜索类似,不同之处在于通过将数组分为三部分而不是两部分来降低时间复杂度。

以下是三元搜索工作的分步说明:
1、初始化:
        从排序数组开始。
        设置两个指针left和right,最初指向数组的第一个和最后一个元素。
2、划分数组:
        计算两个中点mid1和mid2,将当前搜索空间分为三个大致相等的部分:
                mid1 = 左 + (右 – 左) / 3
                mid2 = 右 – (右 – 左) / 3
        该数组现在有效地分为[left, mid1]、(mid1, mid2 ) 和[mid2, right]。
3、与目标比较: .
        如果target等于mid1或mid2处的元素,则查找成功,并返回索引
        如果目标小于mid1处的元素,则将右指针更新为mid1 – 1。
        如果目标大于mid2处的元素,则将左指针更新为mid2 + 1。
        如果目标位于mid1和mid2的元素之间,则将左指针更新为mid1 + 1,将右指针更新为mid2 – 1。
4、重复或结论:
        使用缩小的搜索空间重复该过程,直到找到目标或搜索空间变空。
        如果搜索空间为空并且未找到目标,则返回一个值,指示目标不存在于数组中。
插图: 

三元搜索的递归实现: 

// C program to illustrate
// recursive approach to ternary search
 
#include <stdio.h>
 
// Function to perform Ternary Search
int ternarySearch(int l, int r, int key, int ar[])
{
    if (r >= l) {
 
        // Find the mid1 and mid2
        int mid1 = l + (r - l) / 3;
        int mid2 = r - (r - l) / 3;
 
        // Check if key is present at any mid
        if (ar[mid1] == key) {
            return mid1;
        }
        if (ar[mid2] == key) {
            return mid2;
        }
 
        // Since key is not present at mid,
        // check in which region it is present
        // then repeat the Search operation
        // in that region
 
        if (key < ar[mid1]) {
 
            // The key lies in between l and mid1
            return ternarySearch(l, mid1 - 1, key, ar);
        }
        else if (key > ar[mid2]) {
 
            // The key lies in between mid2 and r
            return ternarySearch(mid2 + 1, r, key, ar);
        }
        else {
 
            // The key lies in between mid1 and mid2
            return ternarySearch(mid1 + 1, mid2 - 1, key, ar);
        }
    }
 
    // Key not found
    return -1;
}
 
// Driver code
int main()
{
    int l, r, p, key;
 
    // Get the array
    // Sort the array if not sorted
    int ar[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
 
    // Starting index
    l = 0;
 
    // end element index
    r = 9;
 
    // Checking for 5
 
    // Key to be searched in the array
    key = 5;
 
    // Search the key using ternarySearch
    p = ternarySearch(l, r, key, ar);
 
    // Print the result
    printf("Index of %d is %d\n", key, p);
 
    // Checking for 50
 
    // Key to be searched in the array
    key = 50;
 
    // Search the key using ternarySearch
    p = ternarySearch(l, r, key, ar);
 
    // Print the result
    printf("Index of %d is %d", key, p);

输出
5 的指数为 4 
50 的指数为 -1

时间复杂度: O(2 * log 3 n)
辅助空间: O(log 3 n)

三元搜索的迭代方法:

// C program to illustrate
// iterative approach to ternary search
 
#include <stdio.h>
 
// Function to perform Ternary Search
int ternarySearch(int l, int r, int key, int ar[])
 
{
    while (r >= l) {
 
        // Find the mid1 and mid2
        int mid1 = l + (r - l) / 3;
        int mid2 = r - (r - l) / 3;
 
        // Check if key is present at any mid
        if (ar[mid1] == key) {
            return mid1;
        }
        if (ar[mid2] == key) {
            return mid2;
        }
 
        // Since key is not present at mid,
        // check in which region it is present
        // then repeat the Search operation
        // in that region
 
        if (key < ar[mid1]) {
 
            // The key lies in between l and mid1
            r = mid1 - 1;
        }
        else if (key > ar[mid2]) {
 
            // The key lies in between mid2 and r
            l = mid2 + 1;
        }
        else {
 
            // The key lies in between mid1 and mid2
            l = mid1 + 1;
            r = mid2 - 1;
        }
    }
 
    // Key not found
    return -1;
}
 
// Driver code
int main()
{
    int l, r, p, key;
 
    // Get the array
    // Sort the array if not sorted
    int ar[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
 
    // Starting index
    l = 0;
 
    // end element index
    r = 9;
 
    // Checking for 5
 
    // Key to be searched in the array
    key = 5;
 
    // Search the key using ternarySearch
    p = ternarySearch(l, r, key, ar);
 
    // Print the result
    printf("Index of %d is %d\n", key, p);
 
    // Checking for 50
 
    // Key to be searched in the array
    key = 50;
 
    // Search the key using ternarySearch
    p = ternarySearch(l, r, key, ar);
 
    // Print the result
    printf("Index of %d is %d", key, p);

输出
5 的指数为 4 
50 的指数为 -1

时间复杂度: O(2 * log 3 n),其中 n 是数组的大小。
辅助空间: O(1)

三元搜索的复杂度分析:
时间复杂度:
        最坏情况:O(log 3 N)
        平均情况: θ(log 3 N)
        最好的情况:Ω(1)
        辅助空间: O(1)

二元搜索与三元搜索:
        二分查找的时间复杂度低于三目查找,因为三目查找的比较次数比二分查找多得多。二分搜索用于查找单调函数的最大值/最小值,而三元搜索用于查找单峰函数的最大值/最小值。
        注意:我们也可以对单调函数使用三元搜索,但时间复杂度会比二分搜索稍高。
优点:
        三元搜索可以找到单峰函数的最大值/最小值,而二元搜索不适用。
        三元搜索的时间复杂度为O(2 * log 3 n),比线性搜索更高效,与二分搜索相当。
        非常适合优化问题。
缺点:
        三元搜索仅适用于有序列表或数组,不能用于无序或非线性数据集。
        与二元搜索相比,三元搜索需要更多时间来查找单调函数的最大值/最小值。

何时使用三元搜索:
        当您有一个大型有序数组或列表并且需要查找特定值的位置时。
        当您需要找到函数的最大值或最小值时。
        当您需要在双调序列中找到双调点时。
        当您必须计算二次表达式时
概括:
        三元搜索是一种分治算法,用于查找给定数组或列表中特定值的位置。
        它的工作原理是将数组分为三部分,并对适当的部分递归地执行搜索操作,直到找到所需的元素。 
        该算法的时间复杂度为 O(2 * log 3 n),比线性搜索更有效,但比二分搜索等其他搜索算法不太常用。 
        需要注意的是,要使三元搜索正常工作,要搜索的数组必须进行排序。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/768824.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

快速部署一个devops平台onnedev

简介 1、强大的代码管理&#xff1a;OneDev提供内置的Git服务器&#xff0c;可实现代码版本控制、分支管理和代码协作。您可以轻松地进行代码查找、导航和讨论&#xff0c;并且可以设置代码保护规则&#xff0c;确保代码的质量和安全性。 2、灵活的CI/CD流程&#xff1a;OneD…

实现Spring Web MVC中的文件上传功能,并处理大文件和多文件上传

实现Spring Web MVC中的文件上传功能&#xff0c;并处理大文件和多文件上传 在Spring Web MVC中实现文件上传功能并处理大文件和多文件上传是一项常见的任务。下面是一个示例&#xff0c;演示如何在Spring Boot应用程序中实现这一功能&#xff1a; 添加Spring Web依赖&#x…

SOC 子模块---中断控制器

中断控制器对soc 中的各个外设进行中断管理&#xff0c;进行优先权排队&#xff0c;并送出IQR信号给CPU&#xff1b; 中断控制器在整个系统中的结构&#xff1a; IRQ<n>来源于不同的中断源&#xff0c;比如&#xff1a;I2C,SPI等&#xff0c;INTC收集这些中断&#xff0…

定时器使用场景与解决方案

概况 定时器的作用是可以实现延迟执行某段代码或周期性地执行某段代码&#xff0c;常见的应用场景包括动画效果、定时刷新数据、定时发送请求等。清除定时器是指取消之前设置的定时器&#xff0c;以防止代码在不需要执行的情况下继续执行。在JavaScript中&#xff0c;可以使用c…

HTTP状态码(3)

HTTP 状态码负责表示客户端 HTTP 请求的返回结果、标记服务器端的处理是否正常、通知出现的错误等工作 状态码告知从服务器端返回的请求结果 状态码的职责是当客户端向服务器端发送请求时&#xff0c;描述返回的请求结果。借助状态码&#xff0c;用户可以知道服务器端是正常…

AIGC实战——Transformer模型

AIGC实战——Transformer模型 0. 前言1. T52. GPT-3 和 GPT-43. ChatGPT小结系列链接 0. 前言 我们在 GPT (Generative Pre-trained Transformer) 一节所构建的 GPT 模型是一个解码器 Transformer&#xff0c;它逐字符地生成文本字符串&#xff0c;并使用因果掩码只关注输入字…

面试问题——redis——缓存穿透、击穿、雪崩

HR&#xff1a;你在项目中的那些场景用到了redis&#xff1f; 1. 缓存穿透问题 &#xff08;项目中使用的方法&#xff09; 2. 缓存击穿 解决办法1&#xff1a;加互斥锁。大量并发时&#xff0c;先让一个人去查&#xff0c;其他人等着。这样剩下人就可在缓存直接获取值。&#…

Web实现名言生成器:JavaScript DOM基础与实例教程

&#x1f31f; 前言 欢迎来到我的技术小宇宙&#xff01;&#x1f30c; 这里不仅是我记录技术点滴的后花园&#xff0c;也是我分享学习心得和项目经验的乐园。&#x1f4da; 无论你是技术小白还是资深大牛&#xff0c;这里总有一些内容能触动你的好奇心。&#x1f50d; &#x…

Linux-安装redis

安装指令 sudo apt-get install redis-server 启动服务 sudo systemctl start redis 查找redis路径 find / -name "filename" linux redis修改密码 sudo nano /etc/redis/redis.conf 找到 "requirepass" 这一行&#xff0c;取消注释并设置新的密码&…

跳蚱蜢(蓝桥杯)

文章目录 跳蚱蜢题目描述答案&#xff1a;20bfs 跳蚱蜢 题目描述 本题为填空题&#xff0c;只需要算出结果后&#xff0c;在代码中使用输出语句将所填结果输出即可。 如下图所示&#xff1a; 有 9 只盘子&#xff0c;排成 1 个圆圈。 其中 8 只盘子内装着 8 只蚱蜢&#xff…

包含多个段的程序

文章目录 包含多个段的程序在代码段中使用数据在代码段中使用栈将数据、代码、栈放入不同的段 包含多个段的程序 在代码段中使用数据 考虑这样一个问题&#xff0c;编程计算以下8个数据的和&#xff0c;结果存在ax 寄存器中&#xff1a;0123H&#xff0c;0456H&#xff0c;07…

自动驾驶技术中大模型的应用与挑战分析

自动驾驶技术中大模型的应用与挑战分析 1. 背景介绍 自动驾驶技术是近年来人工智能领域的研究热点&#xff0c;它通过计算机视觉、传感器融合、决策规划等技术的综合应用&#xff0c;实现车辆的自主驾驶。随着深度学习技术的快速发展&#xff0c;大模型在自动驾驶领域得到了广…

电机无感算法采集电流的作用

电机无感算法中采集电流的作用是通过测量电机终端的电流&#xff0c;从中获得电机的状态信息&#xff0c;进而实现对电机旋转位置的估算。 采集电流的作用有以下几个方面&#xff1a; 电机模型建立&#xff1a;通过测量电流&#xff0c;可以获得电机的输入量和输出量之间的关系…

ctfshow web入门 反序列化

254 分析代码&#xff1a; 如果用户名和密码参数都存在&#xff0c;脚本会创建一个 ctfShowUser 类的实例 $user。 接着&#xff0c;调用 $user->login($username, $password) 方法尝试登录。如果登录成功&#xff08;即用户名和密码与类中的默认值匹配&#xff09;&#…

甲方信息安全建设经验

网络系统安全建设 安全域划分 内部网络系统&#xff1a;主要指OA办公网内部、生产网内部、测试开发网内部、以及其他内部网络系统。 外部网络系统&#xff1a;主要指OA办公网互联网边界、生产网互联网边界、测试开发网互联网边界、互联网上相关所属的网络系统&#xff08;不…

地图爬虫工具 百度高德腾讯地图商家电话采集软件使用指南

使用地图爬虫工具可以方便地从百度、高德、腾讯地图等地图服务中获取商家的电话号码。下面是使用指南&#xff0c;并附带代码示例。 使用地图爬虫工具之前&#xff0c;我们需要安装相关的依赖库。建议使用Python作为开发语言&#xff0c;因为Python有一些非常好用的爬虫库可供…

详解机器学习概念、算法

目录 前言 一、常见的机器学习算法 二、监督学习和非监督学习 三、常见的机器学习概念解释 四、深度学习与机器学习的区别 基于Python 和 TensorFlow 深度学习框架实现简单的多层感知机&#xff08;MLP&#xff09;神经网络的示例代码&#xff1a; 欢迎三连哦&#xff01; 前言…

Spark Map 和 FlatMap 的比较

Spark Map 和 FlatMap 的比较 本节将介绍Spark中map(func)和flatMap(func)两个函数的区别和基本使用。 函数原型 map(func) 将原数据的每个元素传给函数func进行格式化&#xff0c;返回一个新的分布式数据集。 flatMap(func) 跟map(func)类似&#xff0c;但是每个输入项和…

JUC(二)

1、wait notify Owner 线程发现条件不满足&#xff0c;调用 wait 方法&#xff0c;即可进入 WaitSet 变为 WAITING 状态 BLOCKED 和 WAITING 的线程都处于阻塞状态&#xff0c;不占用 CPU 时间片 BLOCKED 线程会在 Owner 线程释放锁时唤醒 WAITING 线程会在 Owner 线程调用 …

Gelato Network的创始人HILMAR ORTH确认出席HackSummit2024区块链开发者大会

随着Web3技术的日新月异&#xff0c;区块链领域正以前所未有的速度席卷全球。在这一变革的浪潮中&#xff0c;备受瞩目的区块链盛会——Hack.Summit() 2024区块链开发者大会&#xff0c;将于2024年4月9日至10日&#xff0c;在香港数码港隆重登场。这一里程碑式的大会不仅标志着…