3 分块查找
算法思想:将待查的元素均匀的分成块,块间按大小顺序排序,块内不排序。
具体的,设待查元素有15 个,将其按关键字大小分成3块,这15个数的排列是一个有序序列,也可以给出无序序列,但也是必须得满足分在第一块中的任意元素小于第二块中的所有数,第二块中的任意元素必须小于第三块中的所有元素。当要查找关键字key的元素时,则先用顺序查找在已建好的索引表中查出key所在的块,再在对应的块中顺序查找key,直到查找成功或着失败。
局限性:若有重复元素,只能查出第一个。
代码:
#include <stdio.h>
/*定义结构体index,用于存储块的结构,并定义结构体数组index_table*/
struct index/*定义块的结构*/
{
int key;
int start;
int end;
}index_table[4];/*定义结构体数组*/
/*自定义search()函数,实现分块查找*/
int search(int key,int a[])
{
int i,j;
i=1;
while (i<=3 && key>index_table[i].key)/*确定在哪个块中*/
i++;
if (i>3)/*大于分得的块数,返回0*/
return 0;
j=index_table[i].start;/*j=块范围的起始值*/
while (j<=index_table[i].end && a[j]!=key)/*在确定的块内查找*/
j++;
if (j>index_table[i].end)/*如果大于块范围的结束值,则说明没有要查找的数,j置0*/
j=0;
return j;
}
/*程序入口函数*/
void main ()
{
int i,j=0,k,key,a[16];
printf("please input the number:\n");
for (int i = 1; i < 16; i++)
scanf("%d",&a[i]);/*输入有小到大15 个数*/
for(i=1;i<=3;i++)
{
index_table[i].start=j+1;/*确定每个块范围的起始值*/
j=j+1;
index_table[i].end=j+4;/*确定每个块范围的结束值*/
j=j+4;
index_table[i].key=a[j];/*确定每个块范围中的最大值*/
}
/*跟踪*/
/*printf("跟踪\n");
printf("%d\n",index_table[1].start);
printf("%d\n",index_table[2].start);
printf("%d\n",index_table[3].start);
printf("%d\n",index_table[1].end);
printf("%d\n",index_table[2].end);
printf("%d\n",index_table[3].end);
printf("%d\n",index_table[1].key);
printf("%d\n",index_table[2].key);
printf("%d\n",index_table[3].key);*/
printf("please input the number which you want to search:\n");
scanf("%d",&key);/*输入要查询的数值*/
k=search(key,a);/*调用函数进行查找*/
if(k !=0)
printf("succsess.the position is :%d\n",k);
else
printf("no found!\n");
}
执行结果:
4 哈希查找
关于哈希算法:—-来自百度经验的说法:哈希算法是一种只能加密,不能解密的密码学算法,可以将任意长度的信息转换成一段固定长度的字符串。这段字符串有两个特点:1、就算输入值只改变一点,输出的哈希值也会天差地别。2、只有完全一样的输入值才能得到完全一样的输出值。3、输入值与输出值之间没有规律,所以不能通过输出值算出输入值。要想找到指定的输出值,只能采用枚举法:不断更换输入值,寻找满足条件的输出值。哈希算法保证了比特币挖矿不能逆向推导出结果。所以,矿工持续不断地进行运算,本质上是在暴力破解正确的输入值,谁最先找到谁就能获得比特币奖励。
算法思想:编程实现一个哈希查找。设哈希长度为11,哈希函数为H(key)= key %11,随机产生待散列的小于50的8个元素,同时采用线性探测再散列的方法处理冲突,任意输入要查找的数据,无论找到与否都给出提示信息。
代码:
#include<stdio.h>
#include<time.h>
#define Max 11/*宏定义*/
#define N 8
int hashtable[Max];/*定义全局变量*/
/*自定义func函数,用于哈希函数的值*/
int func(int value)
{
return value % Max;/*哈希函数*/
}
/*自定义search()函数,实现哈希查找*/
int search (int key)
{
int pos,t;
pos=func(key);/*哈希函数确定的位置*/
t=pos;/*t存放确定出的位置*/
while (hashtable[t]!=key && hashtable[t]!= -1)/*如果该位置上不等于要查找的关键字且不为空*/
{
t=(t+1) % Max;/*利用线性探测求出下一个位置*/
if(pos==t)
return -1;/*如果经多次探测又回到原来用哈希函数求出的位置说明要查找的数不存在*/
}
if(hashtable[t]== -1)
return NULL;
else
return t;
}
/*自定义creathash()函数,实现哈希表创建*/
void creathash(int key)
{
int pos,t;
pos=func(key);/*哈希函数确定元素的位置*/
t=pos;
while(hashtable[t]!= -1)/*如果该位置有元素存在则进行线性探测在散列*/
{
t=(t+1)% Max;
if(pos==t)/*如果冲突处理后确定的位置与原位置相同则说明哈希表已满*/
{
printf("hash table is full\n");
return;
}
}
hashtable[t]=key;/*将元素放进确定的位置*/
}
main()
{
int flag[50];
int i,j,t;
for (i=0;i<Max;i++)
hashtable[i]= -1;/*哈希表中初始值全置为-1*/
for (int i = 0; i < 50; i++)
flag[i]=0;/*50 以内所有数字为产生时均标志为0*/
srand((unsigned long)time(0));/*利用系统时间做种子产生随机数*/
i=0;
while (i!=N)
{
t = rand() % 50;/*产生一个50以内的随机数赋给t*/
if(flag[t] == 0)/*看t是否产生过*/
{
creathash(t);/*调用函数创建哈希表*/
printf("%2d:",t);/*将该元素输出*/
for (int j = 0; j < Max; j++)
printf("(%2d)",hashtable[j] );/*输出哈希表中的内容*/
printf("\n");
flag[t]=1;/*将产生的这个数标志为1*/
i++;/*i自加*/
}
}
printf("please input the number which do you want to search:\n");
scanf("%d",&t);/*出入要查找的数*/
if(t>0 && t<50)
{
i=search(t);/*调用函数进行哈希查找*/
if(i != -1)
printf("success! the position is:%d\n",i);/*若找到该元素则输出其位置*/
else
printf("sorry! no found!\n");/*未找到输出提示信息*/
}
else
printf("input error!\n");
}
执行结果: