查找
查找方法有很多种,在这里为大家分享3中简单的查找方式。
以二维数组为例:
现在有一个二维数组,里面的数据由左到右,有上到下均递增,并且值不会重复,在这些数据中找到key
- 顺序查找
#include <stdio.h>
int main()
{
int a[100][100];
int key;
int flag=1;
int m,n;//横行,竖列
scanf("%d",&key);
scanf("%d %d",&m,&n);
for (int i=0;i<m;i++)
for (int j=0;j<n;j++)
scanf("%d",&a[i][j]);
//此时将需要查找的数据,和要查找的数组已经选取好了
for(int i=0;i<m;i++)
for(int j=0;j<n;j++)
if(key==a[i][j])
{
flag=0;
printf ("%d %d %d\n",a[i][j],i,j);
break;
}
if(flag)
printf("no find");
return 0;
}
这样的查找方式,如果这个数组是最后一次,那就要寻找i*j次。
时间复杂度是n(o2)。
由此可见,这样的程序并不完美
- 二分法查找
#include <stdio.h>
int main()
{
int a[100][100];
int key;
int flag=1;
int m,n;//横行,竖列
scanf("%d",&key);
scanf("%d %d",&m,&n);
for (int i=0;i<m;i++)
for (int j=0;j<n;j++)
scanf("%d",&a[i][j]);
//此时将需要查找的数据,和要查找的数组已经选取好了
int i=0,j=n-1;
while(i==m||j==-1)//查找的数字不会同时到达a[m][-1]这一位置
{
if(key>a[i][j])
i++;
else if(key<a[i][j])
j--;
else
{
flag=0;
printf("%d %d %d\n",a[i][j],i,j);
break;
}
}
if(flag)
printf("no find");
return 0;
}
此时,虽然存数据的时候使用的是二位数字,但是在查找的时候,i和j的变化,让时间复杂度瞬间减少为n(1)
如果要使用函数,函数的返回值不会有两个数,因此要使用指针对数据进行改变。
#include <stdio.h>
#define N 4
void foundkey(int a[N][N],int *pm,int *pn);
int main()
{
int a[N][N]={ };//这里采用N*N的方阵,数组的初始化自己进行
int m=-1,n=-1;
printf("%d %d %d",a[m][n],m,n);
foundkey(a,&m,&n);
return 0;
}
void foundkey(int a[N][N],int *pm,int *pn,int key)
{
scanf("%d",&key);
int i=0,j=N-1;
while(i==N||j==-1)
{
if(key>a[i][j])
i++;
else if(key<a[i][j])
j--;
else
{
*pm=i;
*pn=j;
}
}
}
这时,使用指针,去改变两个数的值。
- 哈希查找(还没有完全掌握)
这里是哈希查找的详细解释和代码实现
哈希表就是一种以键-值(key-indexed) 存储数据的结构,只要输入待查找的值即key,即可查找到其对应的值。
如果所有的键都是整数,那么就可以使用一个简单的无序数组来实现:将键作为索引,值即为其对应的值,这样就可以快速访问任意键的值。
- 用给定的哈希函数构造哈希表;
- 根据选择的冲突处理方法解决地址冲突;
常见的解决冲突的方法:拉链法和线性探测法。 - 在哈希表的基础上执行哈希查找。
单纯论查找复杂度:对于无冲突的Hash表而言,查找复杂度为O(1)
(注意,在查找之前我们需要构建相应的Hash表)。
关于时间复杂度,在较小的数字下运行会很快,但是如果数字较大,一层循环就是n(o),两层就是n(o2),三层就是n(o3),指数增长使得电脑的运算效率急剧降低。
兑换货币这个算法优化就可以很明显的看出来。