查找
查找——也叫检索,是根据给定的某个值,在表中确定一个关键字等于给定值的记录或数据元素
关键字——是数据元素中某个数据项的值,它可以标识一个数据元素。
查找方法评价
查找速度;
占用存储空间多少;
算法本身复杂程度;
平均查找长度ASL(Average Search Length):为确定记录在表中的位置,需和给定值进行比较的
关键字的个数的期望值。
静态查找表
查找过程:从表的一端开始逐个进行记录的关键字和给定值的比较。
改进: 将数据元素按访问频度升序排列,可降低ASL
代码展示
#include<stdio.h>
int s_search(int num[],int element,int len)
{
int i;
for (i = 0; i < len; i++) {
if (num[i] == element)
return i + 1;
}
return 0;
}
int main()
{
int num[10] = { 12,23,34,45,56,11,34,56.78,99 };
printf("%d", s_search(num, 11, sizeof(num) / sizeof(int)));//分别传入数组,目标值,数组长度
return 0;
}
折半查找
查找过程:每次将待查记录所在区间缩小一半;
适用条件:采用顺序存储结构的有序表;
算法实现
设表长为n,low、high和mid分别指向待查元素所在区间的上界、下界和中点,k为给定值
初始时,令low=1,high=n,mid=⌊(low+high)/2⌋
让k与mid指向的记录比较
若k==num[mid],查找成功
若k<num[mid],则high=mid-1
若k>num[mid],则low=mid+1
重复上述操作,直至low>high时,查找失败
查找成功
查找失败
代码展示:
#include<stdio.h>
int z_search(int num[], int element, int len)
{
int low = 0, hight = len - 1, mid = (low + hight) / 2;
for (int i = 0; i < len; i++) { //给数组元素排序
for (int j = i + 1; j < len; j++) {
if (num[i] > num[j]) {
int tem = num[i];
num[i] = num[j];
num[j] = tem;
}
}
}
while (low <= hight) { //循环匹配
if (num[mid] < element) { //中间元素小于目标元素要更新右指针
low = mid + 1;
}
else if (element < num[mid]) { //中间元素大于目标元素要更新左指针
hight = mid - 1;
}
else {
return mid;
}
mid = (low + hight) / 2; //更新mid
}
return 0;
}
int main()
{
int num[10] = { 12,23,34,45,56,11,34,56.78,99 };
printf("%d\n", z_search(num, 23, sizeof(num) / sizeof(int)));
return 0;
}
分块查找——索引顺序表的查找
查找过程:将表分成几块,块内无序,块间有序;先确定待查记录所在块,再在块内查找。
适用条件:分块有序表。
算法描述
用数组存放待查记录,每个数据元素至少含有关键字域;
建立索引表,每个索引表结点含有最大关键字域和指向本块第一个结点的指针。
数据结构
typedef struct
{
int key;
int iink;
}SD;
typedef struct
{
int key;
float info;
}JD;
过程
代码展示
#include<stdio.h>
typedef struct
{
int key;
int link;
}SD;
int b_search(SD nd[],int num[], int n, int len, int element)
{
int i = 0;
while ((element < nd[i].key) && (i < len)) //查找块
i++;
if (i >= len) { //若i大于索引长
printf("\nNot found");
return(0);
}
for (int j = nd[i].link; j < nd[i].link + n; j++) { //匹配元素
if (num[j] == element) {
return j + 1;
}
}
printf("\nNot found");
return 0;
}
int main()
{
int num[10] = { 12,23,34,45,56,11,34,56,78,99 };
int l = sizeof(num) / sizeof(int), n = 5, m;
SD nu[2];
for (int i = 0; i < l; i++) { //排序
for (int j = i + 1; j < l; j++) {
if (num[i] > num[j]) {
int tem = num[i];
num[i] = num[j];
num[j] = tem;
}
}
}
if (l%n != 0) //求索引长
m = l / n + 1;
else
m = l / n;
for (int i = 0; i < m; i++) { //建索引
nu[i].key = num[i*n];
nu[i].link = i*n;
}
printf("%d\n", b_search(nu, num, n, m, 23));
return 0;
}
三种静态查算法比较
查找还有有很多技巧的,要灵活使用还是需要多练习啊,加油!朋友们下次见!!!我是孤城浪人,一名正在前端路上摸爬滚打的菜鸟,欢迎你的关注。