資料結構之查詢演算法
一、 實驗目的
1. 掌握查詢的不同方法,並能用高階語言實現查詢演算法;
2. 熟練掌握二分查詢法的構造和查詢方法。
3. 熟練掌握雜湊表查詢方法。
二、 實驗內容
1. 編寫一個程式,輸出在順序表中採用二分查詢法查詢給定關鍵字的過程。
2. 編寫一個程式,輸出在順序表{8、14、6、9、10、22、34、18、19、31、40、38、54、66、46、71、78、68、80、85、100、94、88、96、87}中採用分塊查詢法(每塊的塊長為5,共有5塊)查詢關鍵字46的過程。
3. 設計一個程式,實現雜湊表的相關運算,並完成如下功能:
(1) 建立序列{16,74,60,43,54,90,46,31,29,88,77}的雜湊表
(2) 在上述雜湊表中查詢關鍵字為29的元素。
三、 實驗要求
1. 使用C語言完成演算法設計和程式設計並上機除錯通過。
2. 撰寫實驗報告,提供實驗結果和資料。
3. 寫出演算法設計小結和心得。
四、 程式原始碼
第一題:
#include<stdio.h>
#include<stdlib.h>
#define OK 1
typedef struct{
int *elem;
int length;
int listsize;
}SSTable;
SSTable L;
int InsertList_Sq(SSTable &L,int i,int e)
{
q=&(L.elem[i]);
for(p=&(L.elem[L.length-1]);p>=q;p--)
*(p+1)=*p;
*q=e;
L.length++;
return OK;
}
int Search_bin(SSTable L,int key){
int low=1,high=L.length,mid=(low+high)/2,i=1,find=0;
while(low<=high&&(!find)){
mid=(low+high)/2;
printf("第%d次查詢的資訊 low=%d\tmid=%d\thigh=%d\t所指向的值=%d\n",i,low,mid,high,L.elem[mid]);
i++;
if(key==L.elem[mid])
find=1;
else
if(key<L.elem[mid]) high=mid-1;
else
low = mid+1;
}
if(find)
return mid;
else
return -1;
}
void main(){
InitList_Sq(L);
int key,m,n,i;
int num;
printf("1:輸入元素.2:輸入想要查詢的關鍵字.3:輸出查詢過程.4:輸出所查詢到的關鍵字\n");
while(1){
printf("輸入選擇\n");
scanf("%d",&i);
switch(i){
case 1:
printf("請輸入要插入的元素個數:");
scanf("%d",&num);
printf("輸入元素");
for(i=1;i<=num;i++){
scanf("%d",&n);
InsertList_Sq(L,i,n);
}
break;
case 2:
printf("輸入關鍵字\n");
scanf("%d",&key);
break;
case 3:
m=Search_bin(L,key);
break;
case 4:
printf("輸出查詢的關鍵字\n");
printf("%d\n",L.elem[m]);
break;
default:
printf("輸入錯誤");
break;
}
}
}
第二題
#include<stdio.h>
#include<stdlib.h>
#define OK 1
typedef struct{
int elem[100];
int length;
}SqList;
SqList L;
typedef struct{
int elem[100];
int link[100];
int length;
}SuoYinTable;
SuoYinTable SY;
int InsertList_Sq(SqList &L,int i,int n)
{
int *p,*q;
q=&(L.elem[i]);
for(p=&(L.elem[L.length-1]);p>=q;p--)
*(p+1)=*p;
*q=n;
L.length++;
return OK;
}
int max(SqList &L,int n,int i)
{
int maxi=1,a=L.length/n;
for(int j=1+a*i;j<=a+a*i;j++)
if(L.elem[maxi]<L.elem[j])
maxi=j;
return maxi;
}
int Search(SuoYinTable &SY,int key)
{
int low=0,high=SY.length-1,mid,i,count=1;
int b=L.length/SY.length;
while(low<=high){
mid=(low+high)/2;
printf("第%d次查詢:low=%d\tmid=%d\thigh=%d\t指向的值是 %d\n",count,low,mid,high,SY.elem[mid]);
if(SY.elem[mid]==key)
return SY.link[mid];
if(SY.elem[mid]>=key)
high=mid-1;
else
low=mid+1;
count++;
}
if(low<SY.length)
{
printf("在第%d塊中查詢元素%d\n",mid+1,key);
int i=low*b;
printf("輸出順序查詢過程:\n");
while (i<low*b+b&& L.elem[i]!=key)
{
i++;
printf("%d ",L.elem[i]);
}
printf("\n");
if (i<=low*b+b)
return i;
else
return -1;
}
return -1;
}
void main()
{
int i,n,num,key;
printf("1.建立順序表,2.建立索引表,3.輸入想要查詢的關鍵字\n");
while(1)
{
printf("請輸入選擇:\n");
scanf("%d",&n);
switch(n)
{
case 1:
printf("輸入元素個數:\n");
scanf("%d",&num);
printf("輸入元素:\n");
for(i=1;i<=num;i++){
scanf("%d",&n);
InsertList_Sq(L,i,n);
}
break;
case 2:
printf("輸入分的塊數:\n");
scanf("%d",&n);
for(i=0;i<n;i++){
SY.elem[i]=L.elem[max(L,n,i)];
}
SY.length=n;
break;
case 3:
printf("輸入關鍵字:\n");
scanf("%d",&key);
i=Search(SY,key);
if(L.elem[i]==key)
printf("元素%d的位置是%d\n",key,i);
else
printf("元素%d不在表中\n",key);
break;
default:
printf("輸入錯誤");
break;
}
}
}
第三題
#include<stdio.h>
#include<stdlib.h>
#define MaxSize 100
#define FALSE 0
#define OK 1
typedef struct{
int elem[100];
int length;
}SqList;
SqList L;
typedef struct {
int key;
} HashTable[MaxSize];
int InsertList_Sq(SqList &L,int i,int e)
{
int *p,*q;
q=&(L.elem[i-1]);
for(p=&(L.elem[L.length-1]);p>=q;p--)
*(p+1)=*p;
*q=e;
L.length++;
return OK;
}
void Create(HashTable ha,SqList &L,int n,int m,int p) {
int i,address;
for (i=0;i<m;i++){
ha[i].key=0;
}
for (i=0;i<n;i++){
address=L.elem[i] % n;
if(ha[address].key){
do{
address=(address+1)%p;
}while(ha[address].key);
}
ha[address].key=L.elem[i];
}
}
int Search(HashTable ha,int p,int n,int k)
{ int i=0,address;
address=k % n;
while (ha[address].key!=0 && ha[address].key!=k)
{ i++;
address=(address+1) % p;
}
if (ha[address].key==k)
return address;
else
return -1;
}
void DispHT(HashTable ha,int n,int m)
{ int i;
printf(" 雜湊表地址:\t");
for (i=0;i<m;i++)
printf(" %3d",i);
printf(" \n");
printf(" 雜湊表關鍵字:\t");
for (i=0;i<m;i++)
if (ha[i].key==0 )
printf(" ");
else
printf(" %3d",ha[i].key);
printf(" \n");
}
void main(){
int key,n,i,m=13,p=13,j;
HashTable ha;
int num;
printf("1:建立順序表.2.輸出建立的建立雜湊表,3.輸入想要查詢的關鍵字\n");
while(1){
printf("輸入選擇\n");
scanf("%d",&i);
switch(i){
case 1:
printf("請輸入元素個數:");
scanf("%d",&num);
printf("輸入元素");
for(i=1;i<=num;i++){
scanf("%d",&n);
InsertList_Sq(L,i,n);
}
break;
case 2:
printf("輸出建立的建立雜湊表\n");
Create( ha,L, num, m, p);
DispHT(ha,num,m);
break;
case 3:
printf("輸入關鍵字\n");
scanf("%d",&key);
j=Search( ha, p,num, key);
if (j!=-1)
printf(" ha[%d].key=%d\n",j,key);
else
printf(" 未找到%d\n",key);
break;
default:
printf("輸入錯誤");
break;
}
}
}
五、 程式執行情況(採用截圖方式給出執行結果)
六、 小結(包括收穫、心得體會、存在的問題及解決問題的方法、建議等)
在本次的實驗中感覺最大的收穫是更加熟悉了連結串列,在編寫的查詢過程前期一直出錯,在複習了書本上的知識後解決了這個問題同時對相關的知識增加了瞭解,本次的實驗不是很難,就是需要在查詢關鍵字的時候需要了解是怎麼樣查詢的,以及查詢的相對的查詢過程,還有雜湊表的建立,其實就是對查詢元素,建立索引表的過程。課後還是需要多加學習的。