算法是找工作笔试面试的必考点,一般算法分为数值算法和非数值算法。
数值算法一般用于工程的计算,比如研究导弹方向之类的工程
非数值算法一般用于系统编程,比如研究程序的运行效率之类的编程
这篇文章谈一谈查找算法,即在一系列数据中去查找我们所要的数据。
线性查找
所谓线性查找,即从头开始,一次将每一个元素与查找目标进行比较,或找到目标,或找不到目标 |
线性查找的平均时间复杂度为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 9
2 4 9 12
4 7 10 13
6 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;
}
查找算法很基础,下一篇文章将学习经典的排序算法