【Unity/C# 基础算法】从入门到进阶:线性、插值与斐波那契查找深度解析

文章目录

  • [【Unity/C# 基础算法】从入门到进阶:线性、插值与斐波那契查找深度解析](# 基础算法】从入门到进阶:线性、插值与斐波那契查找深度解析)
    • [1. 线性查找 (Linear Search)](#1. 线性查找 (Linear Search))
      • [1.1 原理](#1.1 原理)
      • [1.2 优缺点](#1.2 优缺点)
    • [1.3 C# 代码实现](# 代码实现)
    • [2. 插值查找 (Interpolation Search)](#2. 插值查找 (Interpolation Search))
      • [2.1 原理](#2.1 原理)
      • [2.2 适用场景](#2.2 适用场景)
      • [2.3 C# 代码实现](# 代码实现)
    • [3. 斐波那契查找 (Fibonacci Search)](#3. 斐波那契查找 (Fibonacci Search))
      • [3.1 原理](#3.1 原理)
      • [3.2 算法逻辑](#3.2 算法逻辑)
      • [3.3 C# 代码实现](# 代码实现)
    • 总结与选择建议

【Unity/C# 基础算法】从入门到进阶:线性、插值与斐波那契查找深度解析

在 Unity 开发中,数据检索是性能优化的重头戏。无论是查找某个特定的 GameObject、管理背包道具,还是从大量的配置表中筛选数据,选择合适的查找算法都能显著提升运行效率。

本文将带你深入理解三种经典的查找算法:线性查找、插值查找以及斐波那契查找,并提供可以直接运行的 C# 代码示例。

1. 线性查找 (Linear Search)

1.1 原理

线性查找是最直观的算法。它不要求数据有序,而是从列表的首项开始,逐个比对,直到找到目标值或遍历完整个序列。

1.2 优缺点

优点:逻辑简单,对数据没有任何预处理要求。
缺点:当数据量很大时,平均搜索时间较长。

1.3 C# 代码实现

csharp 复制代码
/// <summary>
/// 线性查找
/// </summary>
/// <param name="arr">数组</param>
/// <param name="target">目标值</param>
/// <returns>目标值的索引,未找到返回 -1</returns>
public static int LinearSearch(int[] arr, int target)
{
    for (int i = 0; i < arr.Length; i++)
    {
        if (arr[i] == target) 
            return i; 
    }
    return -1;
}

时间复杂度: O ( n ) O(n) O(n)

空间复杂度: O ( 1 ) O(1) O(1)

2. 插值查找 (Interpolation Search)

2.1 原理

插值查找是对 二分查找 (Binary Search) 的智能改进。二分查找总是从 1 / 2 1/2 1/2 处开始,而插值查找则会根据目标值的大小,动态预测它可能出现的位置。

其核心思想类似于我们在查字典时,找 "A" 开头的单词会从前面翻,找 "Z" 开头的会从后面翻。

计算位置的公式为:

p o s = l o w + ( t a r g e t − a r r l o w ) × ( h i g h − l o w ) a r r h i g h − a r r l o w pos = low + \frac{(target - arrlow) \times (high - low)}{arrhigh - arrlow} pos=low+arrhigh−arrlow(target−arrlow)×(high−low)

2.2 适用场景

数据必须是有序的。

数据分布较为均匀。如果分布极度不均(如数据突然跳跃很大),其性能可能不如二分查找。

2.3 C# 代码实现

csharp 复制代码
public static int InterpolationSearch(int[] arr, int target)
{
    int low = 0;
    int high = arr.Length - 1;

    // 确保目标值在数组范围内,避免计算出的 pos 越界
    while (low <= high && target >= arr[low] && target <= arr[high])
    {
        if (low == high)
        {
            return arr[low] == target ? low : -1;
        }

        // 关键:自适应探测位置计算
        int pos = low + (int)((double)(target - arr[low]) / (arr[high] - arr[low]) * (high - low));

        if (arr[pos] == target) 
            return pos;
        
        if (arr[pos] < target) 
            low = pos + 1;
        else 
            high = pos - 1;
    }
    return -1;
}

时间复杂度: 平均 O ( log ⁡ ( log ⁡ n ) ) O(\log(\log n)) O(log(logn)),最坏 O ( n ) O(n) O(n)。

3. 斐波那契查找 (Fibonacci Search)

3.1 原理

斐波那契查找同样利用了有序数组的特性。它巧妙地利用 黄金分割原理。

它将数组长度扩展到某个斐波那契数 F k − 1 Fk-1 Fk−1,然后利用 F k − 1 Fk-1 Fk−1 和 F k − 2 Fk-2 Fk−2 将区间分为两部分。这种算法最大的特点是:它在循环中只使用 加减法,而不涉及除法或乘法,这在某些底层硬件或极致性能优化中具有优势。

3.2 算法逻辑

生成一个斐波那契数列。

找到大于等于数组长度的最小斐波那契数 F k Fk Fk

将原数组拷贝并填充至 F k − 1 Fk-1 Fk−1 长度(通常用末尾元素填充)。

通过 i = o f f s e t + F k − 2 i = offset + Fk-2 i=offset+Fk−2 进行分割查找。

3.3 C# 代码实现

csharp 复制代码
public static int FibonacciSearch(int[] arr, int target)
{
    int n = arr.Length;
    int fib2 = 0; // F[k-2]
    int fib1 = 1; // F[k-1]
    int fibK = fib1 + fib2; // F[k]

    // 1. 确定 F[k]
    while (fibK < n)
    {
        fib2 = fib1;
        fib1 = fibK;
        fibK = fib1 + fib2;
    }

    int offset = -1;

    while (fibK > 1)
    {
        // 确定分割点
        int i = Math.Min(offset + fib2, n - 1);

        if (arr[i] < target)
        {
            // 目标在右部,下移两级
            fibK = fib1;
            fib1 = fib2;
            fib2 = fibK - fib1;
            offset = i;
        }
        else if (arr[i] > target)
        {
            // 目标在左部,下移一级
            fibK = fib2;
            fib1 = fib1 - fib2;
            fib2 = fibK - fib1;
        }
        else return i;
    }

    // 最后一个元素检查
    if (fib1 == 1 && offset + 1 < n && arr[offset + 1] == target) 
        return offset + 1;

    return -1;
}

时间复杂度: O ( log ⁡ n ) O(\log n) O(logn)

优点: 核心运算仅需加减法,效率稳定且符合黄金比例分割。

总结与选择建议

算法 数据要求 平均复杂度 适用 Unity 场景
线性查找 无序 O ( n ) O(n) O(n) 简单的 UI 列表、小型动态数组
插值查找 有序且分布均匀 O ( log ⁡ ( log ⁡ n ) ) O(\log(\log n)) O(log(logn)) 大型静态数值配置表(如等级经验表)
斐波那契查找 有序 O ( log ⁡ n ) O(\log n) O(logn) 底层性能优化、避免除法开销的系统

博主寄语

如果你觉得这篇文章对你有帮助,欢迎点赞、收藏并关注!我是 小郎君,我们下期见!

相关推荐
Artech5 小时前
[MAF预定义的AIContextProvider-02]AgentSkillsProvider——将Agent Skills引入MAF
ai·c#·agent·agent skills·maf
2601_962072551 天前
李梦娇常识4600问|题库|打印版
sql·华为od·华为·c#·华为云·.net·harmonyos
m0_547486661 天前
《C#语言程序设计与实践》 全套PPT课件
c语言·c#·c语言程序设计
叶帆1 天前
【YFIOs】用C#开发硬件之设备上云
开发语言·unity·c#
IT方大同1 天前
(嵌入式操作系统)信号量
嵌入式硬件·c#
z落落1 天前
C# FileStream文件流读取文件
开发语言·c#
yngsqq1 天前
排版优化 异形排版
c#
苦学的罐头1 天前
C# 协变与逆变深度解析:为什么 IEnumerable<T> 能转换,而 List<T> 不行?
开发语言·c#·list
FuckPatience1 天前
使用ReactiveUI 前端绑定不生效
c#