数据结构之查找算法

来源:互联网 发布:红圈通是什么样的软件 编辑:程序博客网 时间:2024/06/04 19:06

算法是找工作笔试面试的必考点,一般算法分为数值算法非数值算法

数值算法一般用于工程的计算,比如研究导弹方向之类的工程

非数值算法一般用于系统编程,比如研究程序的运行效率之类的编程

这篇文章谈一谈查找算法,即在一系列数据中去查找我们所要的数据。

线性查找

所谓线性查找,即从头开始,一次将每一个元素与查找目标进行比较,或找到目标,或找不到目标

线性查找的平均时间复杂度为O(N),对被查找的数据没有任何规律性的要求

下面是一个简单的线性查找的接口:

size_t line_find(int data[], size_t size, int key) //data为我们已知的数组,size为数组大小,key为我们要查找的元素{    size_t i;    for(i = 0; i < size; i++)    {        if(data[i] == key)        {            return i;        }    }    return -1;  }

二分法查找

假设表中元素按照升序排列,我们先找中间元素,然后利用中间元素将表划分为前后两个子表,就这样循环查找。

二分法查找的平均时间复杂度为O(logN),被查找的数据必须为有序的,如果我们先对其进行排序,那么数组的下标位置会被改变,不利于我们的查找,然后排序也会浪费我们一部分时间

下面是一个实现二分法查找的接口:

size_t half_find(int data[], size_t size, int key) //data为数组,size为数组大小,key为要查找的元素{    int left = 0;    int right = size - 1;    while(left <= right)    {        int mid = (left + right) / 2;        if(key < data[mid])        {            right = mid - 1;        }        else if(data[mid] < key)        {            left = mid + 1;        }        else        {            return mid;        }    }    return -1;}       

下面给个测试用例:

int main(int argc, char **argv){               srand(time(NULL));    int data[10];    size_t i;    size_t size = sizeof(data) / sizeof(data[0]);    for(i = 0; i < size; i++)    {        printf("%d ", data[i] = /*rand() % 100*/i);    }    printf("\n");    printf("查找目标:");    int key;    scanf("%d", &key);    printf("查找结果:");    //i = line_find(data, size, key);  //线性查找    i = half_find(data, size, key);  //二分法查找    if(i == (size_t) - 1)    {        printf("失败!\n");    }    else    {        printf("[%u] %d\n", i, data[i]);    }    return 0;}

下面是一个关于查找算法的题目:

设计一个查找算法函数,返回匹配元素的下标
数组:1 2 8 9 2 4 9 12 4 7 10 13 6 8 11 15

一般人一看就以为这是用线性查找方法,但是其实这道题考的是二分法的思想。

这个数组的规律可以看出,每四个数字是按照顺序排列的,也就是可以使用我们的二分法查找。然后用矩阵的形式将这个数组表达出来:

1 2  8  92 4  9 124 7 10 136 8 11 15每行每列都是按升序排列的,然后每个右上角的数即可作为中间值来使用二分法。

程序:

#include <stdio.h>size_t find(int data[], int rows, int cols, int key)//定义行号和列号确定下标{    if(!data || !rows || !cols)    {        return -1;    }    int row = 0;    int col = cols - 1;    while(row < rows && col >= 0)    {        size_t i = row * cols + col;        if(key < data[i])        {            --col;        }        else if(data[i] < key)        {            ++row;        }        else        {            return i;        }    }    return -1;}int main(int argc, char **argv){    int data[] = {1, 2, 8, 9, 2, 4, 9, 12, 4, 7, 10, 13, 6, 8, 11,    15};    int j = 0;    for(j = 0; j < 16; j++)    {        printf("%d ", data[j]);    }    printf("\n");    int key;    printf("请输入要查找的数:");    scanf("%d", &key);    size_t i = find(data, 4, 4, key);    if(i == (size_t)-1)    {        printf("查找失败!\n");    }    else    {        printf("[%u] %d\n", i, data[i]);    }    return 0;}

查找算法很基础,下一篇文章将学习经典的排序算法

原创粉丝点击