3.查找算法:顺序查找和二分查找

查找

查找,是指在一些数据元素中,通过一定的方法找出与给定关键字相同的数据元素的过程。

列表查找(线性表查找):从列表中查找指定元素

输入:列表,待查找元素

输出:元素下标(未查找到元素时返回-1)

顺序查找(线性查找)

  1. 顺序查找(linear search)

也叫线性查找(linear search),从列表的第一个元素开始,顺序的进行查找,直到找到元素或搜索到列表的最后一个元素为止。

代码:

//C版本
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#define ARR_SIZE 10

int linear_search(const int *arr, const int n, const int val)
{
    for (int i = 0; i < n; i++)
    {
        if (arr[i] == val)
            return i;
    }

    return -1;
}

int main(int argc, char *argv[])
{
    srand(time(NULL));

    int arr[ARR_SIZE] = {0};
    int val = rand()%10 + 1;
    int index = -1;

    printf("arr = ");
    for (int i = 0; i < ARR_SIZE; i++)
    {
        arr[i] = rand()%10 + 1;
        printf("%d ", arr[i]);
    }
    printf("\n");

    printf("search val = %d\n", val);
    index = linear_search(arr, ARR_SIZE, val);
    printf("index = %d\n", index);

    return 0;
}
//C++版本
#include <iostream>
#include <cstdlib>
#include <ctime>
using namespace std;

#define ARR_SIZE 10

template<typename T>
int linear_search(const T *arr, const int n, const T val)
{
    for (int i = 0; i < n; i++)
    {
        if (arr[i] == val)
            return i;
    }

    return -1;
}

int main(int argc, char *argv[])
{
    srand(time(NULL));

    int arr[ARR_SIZE] = {0};
    int val = rand()%10 + 1;
    int index = -1;

    cout << "arr = ";
    for (int i = 0; i < ARR_SIZE; i++)
    {
        arr[i] = rand()%10 + 1;
        cout << arr[i] << " ";
    }
    cout << endl;

    cout << "search val = " << val <<endl;
    index = linear_search(arr, ARR_SIZE, val);
    cout << "index = " << index << endl;

    return 0;
}

结果:

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

顺序查找算法最差的情况,需要循环n次,所以该算法的时间复杂度为O(n)

二分查找法

  1. 二分查找法(binary)

又叫折半查找,从有序的列表初始选区[0 n-1]开始,即下标left = 0,right = n - 1,通过待查找的值与候选区中间(即下标为mid)的值继续比较。可以使候选区减少一半。

代码:

//C版本
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#define ARR_SIZE 10

int binary_search(const int *arr, const int n, const int val)
{
    int left = 0;
    int right = n-1;
    int mid;

    while (left <= right)
    {
        mid = (left + right)/2;
        if (arr[mid] == val)
            return mid;
        else if (arr[mid] > val) //候选区在左区
            right = mid - 1;
        else //候选区在右区
            left = mid + 1;
    }

    return -1;
}

int main(int argc, char *argv[])
{
    srand(time(NULL));

    int arr[ARR_SIZE] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
    int val = rand()%10 + 1;
    int index = -1;

    printf("arr = ");
    for (int i = 0; i < ARR_SIZE; i++)
        printf("%d ", arr[i]);
    printf("\n");

    printf("search val = %d\n", val);
    index = binary_search(arr, ARR_SIZE, val);
    printf("index = %d\n", index);

    return 0;
}
//C++版本
#include <iostream>
#include <cstdlib>
#include <ctime>
using namespace std;

#define ARR_SIZE 10

template<typename T>
int binary_search(const T *arr, const int n, const T val)
{
    int left = 0;
    int right = n-1;
    int mid;

    while(left <= right)
    {
        mid = (left + right)/2;
        if (arr[mid] == val)
            return mid;
        else if (arr[mid] > val) //候选区在左区
            right = mid - 1;
        else //候选区在右区
            left = mid + 1;
    }

    return -1;
}

int main(int argc, char *argv[])
{
    srand(time(NULL));

    int arr[ARR_SIZE] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
    int val = rand()%10 + 1;
    int index = -1;

    cout << "arr = ";
    for (int i = 0; i < ARR_SIZE; i++)
        cout << arr[i] << " ";
    cout << endl;

    cout << "search val = " << val <<endl;
    index = binary_search(arr, ARR_SIZE, val);
    cout << "index = " << index << endl;

    return 0;
}

结果:

  1. 时间复杂度:,或logn

二分查找算法,每次执行可以使候选区减少一半,所以时间复杂度为:或logn

顺序查找和二分查找比较

通过以上分析,顺序查找的算法时间复杂度为:O(n),二分查找的算法时间复杂度为:

  1. 如果需要查找时,并且被查找的列表有序,那么选择二分查找,执行效率会比顺序查找快很多。

  1. 如果需要查找时,被查找的列表无序,就选择顺序查找。但是,如果需要频繁查找时,我们可以选择先对被查找的列表进行排序,然后在选择二分查找,从而提高查找的效率。

ending😃

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值