Java实现查找算法的示例代码(二分查找、插值查找、斐波那契查找)

Java实现查找算法的示例代码

在Java中,实现查找算法的方式有很多,包括线性查找、二分查找、插值查找、哈希查找等等。本文将详细讲解Java中实现三种常见的查找算法:二分查找、插值查找、斐波那契查找。

二分查找

二分查找也称为折半查找,是一种效率较高的查找算法。二分查找的条件是数据必须是有序的,每次查找都是将查找区间缩小一半,直到查找到目标或者查找区间为空为止。

二分查找的实现可以采用循环或递归的方式,下面是二分查找的示例代码:

public 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) {
            left = mid + 1;
        } else if (arr[mid] > target) {
            right = mid - 1;
        } else {
            return mid;
        }
    }
    return -1;
}

示例说明:

在上面的代码中,首先定义了左右两个指针left和right,表示查找区间的左右两端。在每一次查找过程中,计算出mid=left+(right-left)/2表示中间位置,然后通过比较mid和target的大小,将查找区间缩小一半。如果arr[mid]target,则在左半区间查找,即将右指针right移动到mid-1位置。如果arr[mid]==target,则找到目标,返回mid。

插值查找

插值查找是对二分查找的改进,它是根据查找值在数组中的大致位置进行估算,从而缩小查找区间。如果数组中的元素分布比较均匀,那么插值查找的效率会比二分查找更高。

插值查找的实现也可以采用循环或递归的方式,下面是插值查找的示例代码:

public int interpolationSearch(int[] arr, int target) {
    int left = 0, right = arr.length - 1;
    while (left <= right) {
        int mid = left + (right - left) * (target - arr[left]) / (arr[right] - arr[left]);
        if (arr[mid] < target) {
            left = mid + 1;
        } else if (arr[mid] > target) {
            right = mid - 1;
        } else {
            return mid;
        }
    }
    return -1;
}

示例说明:

在上面的代码中,首先定义了左右两个指针left和right,表示查找区间的左右两端。在每一次查找过程中,计算出mid=left+(right-left)*(target-arr[left])/(arr[right]-arr[left]),表示平均分配,因此可以将查找区间近似看作等差数列,从而可以比较平均地猜测目标元素所在的位置。然后通过比较mid和target的大小,将查找区间缩小。如果arr[mid]target,则在左半区间查找,即将右指针right移动到mid-1位置。如果arr[mid]==target,则找到目标,返回mid。

斐波那契查找

斐波那契查找是利用斐波那契数列进行查找的一种方法,与二分查找和插值查找不同,它不是通过平均分配的方式来确定查找点,而是利用黄金分割原理来确定查找点。

斐波那契查找的实现可以采用递归或非递归的方式,下面是斐波那契查找的示例代码:

public int fibonacciSearch(int[] arr, int target) {
    int n = arr.length;
    int k = 0;
    while (fibonacci(k + 1) - 1 < n) k++;
    int left = 0, right = n - 1;
    while (left <= right) {
        int mid = left + fibonacci(k - 1) - 1;
        if (arr[mid] < target) {
            left = mid + 1;
            k -= 2;
        } else if (arr[mid] > target) {
            right = mid - 1;
            k--;
        } else {
            return mid;
        }
    }
    return -1;
}

private int fibonacci(int n) {
    if (n == 0 || n == 1) {
        return n;
    }
    int a = 0, b = 1;
    int res = 0;
    for (int i = 2; i <= n; i++) {
        res = a + b;
        a = b;
        b = res;
    }
    return res;
}

示例说明:

在上面的代码中,首先定义了斐波那契数列,在计算出n<=斐波那契数列第k个数的最大下标k后,初始化左右两个指针left和right,表示查找区间的左右两端。在每一次查找过程中,计算mid=left+fibonacci(k-1)-1,其中fibonacci(k-1)-1用来确定黄金分割点,并将查找区间缩小。如果arr[mid]target,则在左半区间查找,即将右指针right移动到mid-1位置,并且k=k-1;如果arr[mid]==target,则找到目标,返回mid。

以上三种查找算法都是较常用的查找算法,特别是在大数据量、组织有序时,查找算法的效果更为明显。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Java实现查找算法的示例代码(二分查找、插值查找、斐波那契查找) - Python技术站

(0)
上一篇 2023年5月19日
下一篇 2023年5月19日

相关文章

  • 什么是Java内存溢出?

    Java内存溢出是指在Java程序运行过程中,申请的内存超过了JVM所能提供的上限,导致程序无法正常运行或者直接导致JVM崩溃。这是Java程序中常见的一个问题,需要我们去识别和解决。 为了解决Java内存溢出问题,我们可以采用以下几个步骤: 第一步:确认内存溢出的类型 Java内存溢出一般分为两类:堆栈内存溢出和非堆栈内存溢出。我们需要根据JVM的错误提示…

    Java 2023年5月11日
    00
  • java算法Leecode刷题统计有序矩阵中的负数

    Java算法Leetcode刷题是大多数Java程序员在提高自己的算法能力时所选择的途径之一。其中,《有序矩阵中的负数》是一道常见的算法题目。下面我将给出一份完整攻略,以便Java程序员能够更好地掌握这道题目。 题目描述 给定一个m*n的矩阵grid,其中每行和每列均已按非递增顺序排好序,请你统计并返回grid中 负数 的个数。 解题思路 因为矩阵已按照非递…

    Java 2023年5月19日
    00
  • Spring boot配置多数据源代码实例

    Spring Boot具有很强的扩展性和灵活性,可以轻松地实现多数据源的配置。下面我将分享一个完整的“Spring Boot配置多数据源代码实例”的攻略,步骤如下: 1.在pom.xml中添加如下配置: <dependency> <groupId>org.springframework.boot</groupId> &lt…

    Java 2023年5月31日
    00
  • Java 模拟数据库连接池的实现代码

    这里为大家介绍一下 Java 模拟数据库连接池的实现代码的完整攻略。 准备工作 在开始实现之前,我们需要引入一些必要的类库和工具,这些工具包括: java.sql 包中的 JDBC API,用于连接数据库。 com.zaxxer.hikari.HikariConfig, com.zaxxer.hikari.HikariDataSource, com.zaxx…

    Java 2023年5月19日
    00
  • 详解Java的编译执行与解释执行

    Java是一种编译型语言,Java源文件在编译时会被编译成Java字节码文件,在Java虚拟机上执行。此时,Java bytecode是被解释执行的。Java程序的执行过程可以被分为两个阶段:编译阶段和运行阶段。 编译阶段 Java源文件在编译时会被编译器编译成特定的字节码文件(.class文件),字节码文件包含了代码经过编译器编译后的中间表达形式。以下是使…

    Java 2023年5月20日
    00
  • 关于Java变量的声明、内存分配及初始化详解

    关于Java变量的声明、内存分配及初始化详解 变量的声明 在Java中,要使用一个变量之前,必须先对其进行声明。变量的声明包括变量类型和变量名。在声明变量时,可以同时对变量进行初始化(赋初值),也可以在后面的步骤中对变量进行赋值。 变量的声明语法格式如下: 变量类型 变量名; 在声明多个同类型的变量时可以使用逗号进行分隔: 变量类型 变量1, 变量2, ..…

    Java 2023年5月26日
    00
  • JavaWeb的监听器和过滤器你了解吗

    让我来详细讲解一下JavaWeb的监听器和过滤器。 监听器 介绍 在JavaWeb中,监听器是用来监听应用程序中发生的事件的组件。事件可以是请求的到来、属性的改变以及session创建和销毁等。监听器可以在事件发生时执行预先定义好的业务逻辑,从而实现对应用程序的控制。JavaWeb中定义了多种类型的监听器,如ServletContextListener、Ht…

    Java 2023年6月15日
    00
  • SpringBoot JSON全局日期格式转换器实现方式

    下面是 SpringBoot JSON 全局日期格式转换器实现方式的攻略: 1. 需求分析 在 SpringBoot 应用中,Java 中的 Date 类型会默认转换为 Unix 时间戳格式,在通过 API 接口返回给前端时,需要对 Date 类型进行格式化。我们可以定义全局的 JSON 转换器来实现日期格式转换。 2. 实现方式 2.1 自定义日期格式化工…

    Java 2023年5月20日
    00
合作推广
合作推广
分享本页
返回顶部