C語言學習_查詢演算法(二)
阿新 • • 發佈:2018-12-09
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");
}
執行結果: