数据结构——查找算法

文章目录

[1. 查找算法](#1. 查找算法)

[2. 顺序查找](#2. 顺序查找)

[2. 二分查找](#2. 二分查找)


1. 查找算法

查找算法是用于在数据集中定位特定元素的位置的算法。查找是计算机科学中一项基本操作,几乎在所有应用程序中都需要使用。例如,数据库查询、信息检索、字典查找等都涉及到查找操作。查找算法可以根据不同的需求和数据结构选择不同的实现方法,以达到高效、准确的目的。

顺序查找

原理:从数据集的起始位置开始,依次检查每个元素,直到找到目标元素或到达数据集末尾。

优点:实现简单。无需数据集有序。

缺点:查找效率较低,时间复杂度为O(n)。

二分查找

原理:在有序数据集中,通过反复将查找范围减半,逐步缩小搜索范围,直到找到目标元素或确定目标元素不存在。

优点

  • 查找效率较高,时间复杂度为O(log n)。
  • 适用于有序数据集。

缺点

  • 需要数据集有序。
  • 实现相对复杂。

2. 顺序查找

顺序查找,又称线性查找,是一种最基本的查找算法。它的工作原理非常简单,主要步骤如下:

  1. 从头开始遍历:从数据集的起始位置开始,依次检查每个元素。
  2. 比较目标:对于每个遍历到的元素,将其与目标元素进行比较。
  3. 查找成功:如果当前元素等于目标元素,则查找成功,返回当前元素的索引。
  4. 查找失败:如果遍历完整个数据集仍未找到目标元素,则查找失败,返回一个特殊的标识来表示未找到。

这种方法的优点在于简单直观,但对于大量数据来说,效率不高,因为它在最坏情况下需要检查每个元素。

伪代码

function linearSearch(array, target):
    for index from 0 to length(array) - 1:
        if array[index] == target:
            return index  // 查找成功,返回索引
    return -1  // 查找失败,返回特殊标识

C代码实现

#include <stdio.h>

// 顺序查找函数
// arr[]: 待查找的数组
// n: 数组的长度
// target: 目标元素
int linearSearch(int arr[], int n, int target) {
    // 遍历数组中的每个元素
    for (int i = 0; i < n; i++) {
        // 如果当前元素等于目标元素
        if (arr[i] == target) {
            return i;  // 查找成功,返回当前元素的索引
        }
    }
    return -1;  // 查找失败,返回特殊标识 -1 表示未找到目标元素
}

int main() {
    int arr[] = {3, 5, 7, 9, 11, 13, 15};  // 定义一个整数数组
    int n = sizeof(arr) / sizeof(arr[0]);  // 计算数组的长度
    int target = 9;  // 定义目标元素

    // 调用顺序查找函数查找目标元素
    int result = linearSearch(arr, n, target);

    // 根据查找结果输出相应的信息
    if (result != -1) {
        printf("元素 %d 在数组中的索引为: %d\n", target, result);  // 查找成功
    } else {
        printf("元素 %d 不在数组中\n", target);  // 查找失败
    }

    return 0;  // 程序结束
}
  • 函数定义linearSearch 函数接收一个数组、数组长度和目标元素作为参数。
  • 遍历数组 :使用 for 循环遍历数组中的每个元素。
  • 比较元素:在循环中,将每个元素与目标元素进行比较。如果相等,则返回当前索引。
  • 查找失败:如果循环结束后仍未找到目标元素,则返回 -1 表示查找失败。
  • 主函数 :在 main 函数中,定义了一个数组和目标元素,调用 linearSearch 函数,并根据返回结果输出相应的信息。

2. 二分查找

二分查找(Binary Search)是一种高效的查找算法,通常用于在有序数据集中查找目标元素。其原理是通过将数据集划分为两半并与目标进行比较,以确定目标在哪一半中,从而逐步缩小搜索范围,直到找到目标元素或确定不存在目标元素。基本原理如下:

1. 选择中间元素:在有序数据集中,选择数组的中间元素。

  • 初始时,选择整个数组的中间元素。对于一个有序数组arr,如果当前的搜索范围是[low, high],则中间元素的位置是mid = (low + high) / 2

2. 比较目标:将中间元素与目标元素进行比较。

  • 将数组中间位置的元素arr[mid]与目标元素target进行比较。

3. 查找成功:如果中间元素等于目标元素,则查找成功,返回中间元素的索引。

  • 如果arr[mid] == target,则找到目标元素,返回mid

4. 缩小搜索范围

  • 对于一个升序的数据集,如果中间元素大于目标元素,说明目标可能在左半部分;如果中间元素小于目标元素,说明目标可能在右半部分。根据比较结果,将搜索范围缩小到左半部分或右半部分,继续查找。
  • 如果arr[mid] > target,则目标元素在左半部分,即更新搜索范围为[low, mid - 1]
  • 如果arr[mid] < target,则目标元素在右半部分,即更新搜索范围为[mid + 1, high]

5. 重复步骤:重复上述步骤,不断将搜索范围缩小,直到找到目标元素或搜索范围为空。

  • 重复上述步骤,直到low > high(搜索范围为空)或找到目标元素。

C代码实现

#include <stdio.h>

// 二分查找函数
int binarySearch(int arr[], int low, int high, int target) {
    while (low <= high) {
        int mid = (low + high) / 2; // 选择中间元素
        if (arr[mid] == target) {
            return mid; // 查找成功,返回索引
        } else if (arr[mid] > target) {
            high = mid - 1; // 缩小搜索范围到左半部分
        } else {
            low = mid + 1; // 缩小搜索范围到右半部分
        }
    }
    return -1; // 查找失败,返回特殊值
}

int main() {
    int arr[] = {1, 2, 3, 4, 5, 6, 7, 8};
    int n = sizeof(arr) / sizeof(arr[0]);
    int target = 5;
    int result = binarySearch(arr, 0, n - 1, target);
    if (result != -1) {
        printf("Element found at index: %d\n", result);
    } else {
        printf("Element not found in array\n");
    }
    return 0;
}
  • 时间复杂度 :二分查找的时间复杂度是O(log n),因为每次比较后搜索范围都会减少一半。
  • 空间复杂度 :由于二分查找只需要几个额外的变量存储索引,因此空间复杂度是O(1)

假设我们有一个有序数组arr = {1, 2, 3, 4, 5, 6, 7, 8},目标元素是5

  1. 初始时,low = 0high = 7,计算mid = (0 + 7) / 2 = 3

    • 比较arr[3](即4)与目标5
    • 因为4 < 5,所以目标在右半部分,更新low = 4
  2. 下一步,low = 4high = 7,计算mid = (4 + 7) / 2 = 5

    • 比较arr[5](即6)与目标5
    • 因为6 > 5,所以目标在左半部分,更新high = 4
  3. 最后,low = 4high = 4,计算mid = (4 + 4) / 2 = 4

    • 比较arr[4](即5)与目标5
    • 因为5 == 5,查找成功,返回索引4

因此,目标元素5在数组中的索引是4

相关推荐
pianmian137 分钟前
python数据结构基础(7)
数据结构·算法
好奇龙猫3 小时前
【学习AI-相关路程-mnist手写数字分类-win-硬件:windows-自我学习AI-实验步骤-全连接神经网络(BPnetwork)-操作流程(3) 】
人工智能·算法
sp_fyf_20243 小时前
计算机前沿技术-人工智能算法-大语言模型-最新研究进展-2024-11-01
人工智能·深度学习·神经网络·算法·机器学习·语言模型·数据挖掘
ChoSeitaku4 小时前
链表交集相关算法题|AB链表公共元素生成链表C|AB链表交集存放于A|连续子序列|相交链表求交点位置(C)
数据结构·考研·链表
偷心编程4 小时前
双向链表专题
数据结构
香菜大丸4 小时前
链表的归并排序
数据结构·算法·链表
jrrz08284 小时前
LeetCode 热题100(七)【链表】(1)
数据结构·c++·算法·leetcode·链表
oliveira-time4 小时前
golang学习2
算法
@小博的博客4 小时前
C++初阶学习第十弹——深入讲解vector的迭代器失效
数据结构·c++·学习
南宫生5 小时前
贪心算法习题其四【力扣】【算法学习day.21】
学习·算法·leetcode·链表·贪心算法