非启发式算法——二分、三分搜索算法

简介: 非启发式算法——二分、三分搜索算法

非启发式算法第一练——二分、三分搜索算法

非启发式算法是一类不依赖于启发式信息或领域知识的问题解决方法。其中,二分搜索和三分搜索算法是两个经典且广泛应用的技术。在本篇博客中,我们将深入了解这两种搜索算法的原理、应用场景以及如何在实际问题中使用它们。

二分搜索算法

原理

二分搜索算法,又称为二分查找,是一种高效的搜索方法。它基于分治思想,适用于已排序的数组或列表。其核心思想是在每一步中将搜索区间缩小一半,直到找到目标或区间为空。

步骤

  1. 确定搜索区间的左右边界。
  2. 计算中间位置的索引。
  3. 检查中间元素是否是目标。
  4. 如果中间元素等于目标,搜索完成。
  5. 如果中间元素大于目标,将搜索区间缩小为左半部分。
  6. 如果中间元素小于目标,将搜索区间缩小为右半部分。
  7. 重复步骤2-6,直到找到目标或区间为空。

应用场景

二分搜索广泛应用于需要在有序数据集中查找元素的场景,例如查找特定值、判定某个条件是否满足等。

示例代码

python

def binary_search(arr, target):
    left, right = 0, len(arr) - 1

    while left <= right:
        mid = (left + right) // 2

        if arr[mid] == target:
            return mid
        elif arr[mid] < target:
            left = mid + 1
        else:
            right = mid - 1

    return -1  # Target not found

Java 实现

public class BinarySearch {

    // 二分搜索算法
    static int binarySearch(int[] arr, int target) {
        int left = 0, right = arr.length - 1;

        while (left <= right) {
            int mid = left + (right - left) / 2;

            if (arr[mid] == target) {
                return mid; // 找到目标,返回索引
            } else if (arr[mid] < target) {
                left = mid + 1; // 缩小搜索区间为右半部分
            } else {
                right = mid - 1; // 缩小搜索区间为左半部分
            }
        }

        return -1; // 目标不在数组中
    }

    public static void main(String[] args) {
        int[] arr = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
        int target = 5;

        int result = binarySearch(arr, target);

        if (result != -1) {
            System.out.println("Target found at index: " + result);
        } else {
            System.out.println("Target not found in the array.");
        }
    }
}

C++ 实现

#include <iostream>
#include <vector>

using namespace std;

// 二分搜索算法
int binarySearch(vector<int>& arr, int target) {
    int left = 0, right = arr.size() - 1;

    while (left <= right) {
        int mid = left + (right - left) / 2;

        if (arr[mid] == target) {
            return mid; // 找到目标,返回索引
        } else if (arr[mid] < target) {
            left = mid + 1; // 缩小搜索区间为右半部分
        } else {
            right = mid - 1; // 缩小搜索区间为左半部分
        }
    }

    return -1; // 目标不在数组中
}

int main() {
    vector<int> arr = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
    int target = 5;

    int result = binarySearch(arr, target);

    if (result != -1) {
        cout << "Target found at index: " << result << endl;
    } else {
        cout << "Target not found in the array." << endl;
    }

    return 0;
}

三分搜索算法

原理

三分搜索算法是二分搜索的扩展,用于在凸函数上寻找极值。与二分搜索不同,三分搜索每次将搜索区间分为三个部分,并根据目标函数值的情况确定下一步搜索的方向。

步骤

  1. 确定搜索区间的左右边界。
  2. 计算两个中间点,将搜索区间分为三部分。
  3. 比较两个中间点的函数值。
  4. 根据函数值的情况,确定搜索区间缩小的方向。
  5. 重复步骤2-4,直到满足停止条件。

应用场景

三分搜索主要用于寻找单峰函数的极值点,例如求解凸函数的最小值或最大值。

示例代码

python

def ternary_search(func, left, right, epsilon=1e-9):
    while right - left > epsilon:
        mid1 = left + (right - left) / 3
        mid2 = right - (right - left) / 3

        if func(mid1) < func(mid2):
            right = mid2
        else:
            left = mid1

    return (left + right) / 2

Java 实现

public class TernarySearch {

    // 三分搜索算法
    static double ternarySearch(double left, double right, double epsilon) {
        while (right - left > epsilon) {
            double mid1 = left + (right - left) / 3;
            double mid2 = right - (right - left) / 3;

            double f1 = function(mid1);
            double f2 = function(mid2);

            if (f1 < f2) {
                right = mid2;
            } else {
                left = mid1;
            }
        }

        return (left + right) / 2;
    }

    // 示例函数(替换成需要寻找极值的函数)
    static double function(double x) {
        // 这里替换成实际的函数表达式
        return x * x;
    }

    public static void main(String[] args) {
        double result = ternarySearch(-10, 10, 1e-9);

        System.out.println("The minimum/maximum value is: " + result);
    }
}

C++ 实现

#include <iostream>

using namespace std;

// 三分搜索算法
double ternarySearch(double left, double right, double epsilon) {
    while (right - left > epsilon) {
        double mid1 = left + (right - left) / 3;
        double mid2 = right - (right - left) / 3;

        double f1 = function(mid1);
        double f2 = function(mid2);

        if (f1 < f2) {
            right = mid2;
        } else {
            left = mid1;
        }
    }

    return (left + right) / 2;
}

// 示例函数(替换成需要寻找极值的函数)
double function(double x) {
    // 这里替换成实际的函数表达式
    return x * x;
}

int main() {
    double result = ternarySearch(-10, 10, 1e-9);

    cout << "The minimum/maximum value is: " << result << endl;

    return 0;
}

结语

二分搜索和三分搜索算法是解决一些特定问题的有力工具。它们的高效性和简单性使它们在算法和编程中得到了广泛的应用。通过深入理解这两种搜索算法的原理和应用场景,我们可以更好地运用它们来解决实际问题。在编写代码时,要根据具体问题选择合适的搜索算法,以提高算法效率。

目录
相关文章
|
2月前
|
算法 机器学习/深度学习 索引
【算法设计与分析】——搜索算法
【算法设计与分析】——搜索算法
40 1
|
2月前
|
算法 程序员 数据处理
算法与人生 揭秘C语言中高效搜索的秘诀——二分查找算法详解
算法与人生 揭秘C语言中高效搜索的秘诀——二分查找算法详解
|
4月前
|
算法 测试技术 C#
【动态规划】【记忆化搜索】【C++算法】664. 奇怪的打印机
【动态规划】【记忆化搜索】【C++算法】664. 奇怪的打印机
|
4月前
|
算法
【算法系列篇】递归、搜索和回溯(四)
【算法系列篇】递归、搜索和回溯(四)
|
2天前
|
算法 搜索推荐 Java
图搜索算法详解
图搜索算法是用于在图结构中寻找特定节点或路径的算法。图是由节点(或顶点)和边组成的集合,节点代表对象,边代表节点之间的连接。图搜索算法广泛应用于各种领域,比如网络路由、社交媒体分析、推荐系统等。 V哥最近总是在多个地方都看到关于图搜索算法的讨论
|
6天前
|
算法
数据结构与算法-Trie树添加与搜索
数据结构与算法-Trie树添加与搜索
5 0
|
16天前
|
机器学习/深度学习 数据采集 算法
Python中基于网格搜索算法优化的深度学习模型分析糖尿病数据
Python中基于网格搜索算法优化的深度学习模型分析糖尿病数据
17 0
|
3月前
|
算法 测试技术 C++
【记忆化搜索】【剪枝】【C++算法】1553吃掉 N 个橘子的最少天数
【记忆化搜索】【剪枝】【C++算法】1553吃掉 N 个橘子的最少天数
|
3月前
|
算法 测试技术 C++
【动态规划】【记忆化搜索】【C++算法】664. 奇怪的打印机
【动态规划】【记忆化搜索】【C++算法】664. 奇怪的打印机
|
3月前
|
移动开发 算法 测试技术
【动态规划】【记忆化搜索】C++算法:546移除盒子
【动态规划】【记忆化搜索】C++算法:546移除盒子