資料結構--C語言--查詢演算法的實現--順序表的查詢
阿新 • • 發佈:2018-12-24
1.實驗目的
熟練掌握順序表和有序表的查詢方法,掌握其時間複雜度的分析方法
2.實驗內容
(1)驗證並設計順序表的查詢(順序查詢、折半查詢)演算法
(2)驗證二叉排序樹上的查詢(建立、查詢、插入)演算法
(3)驗證Hash表查詢(Hash函式定義、建立,查詢,插入)演算法
//順序表的順序查詢 折半查詢 二叉排序樹 以數值型關鍵字為例 #include<stdio.h> #include<stdlib.h> #define MAXSIZE 100 #define INCRESIZE 20 #define EQ(a,b) a==b #define LT(a,b) a<b #define LQ(a,b) a<=b #define ERROR 0 #define FALSE 0 #define TRUE 1 #define OK 1 typedef int ElemType; typedef int KeyType; typedef int Status; typedef struct{ ElemType *base; int length;//表長度 0號單元不儲存內容 }SSTable; typedef struct BTNode{ ElemType data; struct BTNode *lchild; struct BTNode *rchild; }BTNode,*BiTree; Status Init_Seq(SSTable &ST){ ST.base = (ElemType *)malloc(MAXSIZE*sizeof(ElemType)); if(!ST.base) return ERROR; ST.length = 0; return OK; } Status Creat_Seq(SSTable &ST){ int count = 1; printf("\n構造順序表,輸入-111意為停止輸入\n"); scanf("%d",ST.base+count); while(ST.base[count]!=-111){ count++; if(count>MAXSIZE){ ST.base = (ElemType *)realloc(ST.base,(MAXSIZE+INCRESIZE)*sizeof(ElemType)); if(!ST.base) return ERROR; } scanf("%d",ST.base+count); } ST.length = --count; return OK; } int Search_Seq(SSTable ST,KeyType key){//0號單元設哨兵 ST.base[0] = key; int i; for(i=ST.length;*(ST.base+i)!=key;i--) ;//空語句 return i; } Status Sort(SSTable &ST){ int min,temp; for(int i=1;i<=ST.length;i++){ min = i; for(int j=i;j<=ST.length;j++){ if(ST.base[min]>ST.base[j]) min = j; } temp = ST.base[min]; ST.base[min] = ST.base[i]; ST.base[i] = temp; } printf("\n\n排序後的序列為:"); for(int i=1;i<=ST.length;i++) printf("%d ",ST.base[i]); } int Search_Bin(SSTable ST,KeyType key){ int low=1,high=ST.length,mid; Sort(ST); while(low<=high){ mid = (low+high)/2; if(EQ(key,ST.base[mid])) return mid; else if(LT(key,ST.base[mid])) high = mid-1; else low = mid+1; } return 0; } Status SearchBST(BiTree T,KeyType key,BiTree f,BiTree &p){//查詢成功p為資料所在結點指標 否則是插入位置指標 f是工作指標 始終指向當前查詢結點的父母 if(!T){ p = f;//直接插入在根結點 return FALSE;//查詢失敗 }else if(EQ(key,T->data)){ p = T; return TRUE;//查詢成功 }else if(LT(key,T->data)){ return SearchBST(T->lchild,key,T,p);//在左子樹中繼續查詢 }else{ return SearchBST(T->rchild,key,T,p);//在右子樹中繼續查詢 } } Status InsertBST(BiTree &T,ElemType e){ BiTree p; if(!SearchBST(T,e,NULL,p)){//如果是空樹的話p返回NULL 不是空樹的話f在SearchBST()裡會做改變 最後查詢失敗時p=f是不為空的 BiTree s = (BiTree)malloc(sizeof(BTNode)); s->data = e; s->lchild = s->rchild = NULL; if(!p) T=s;//空樹 else if(p->data>e) p->lchild = s;//已經查詢到了葉子結點處 else p->rchild = s; return TRUE; } return FALSE; } Status CreatBST(BiTree &T){ printf("\n\n建立一棵二叉排序樹,輸入-111意為停止\n"); ElemType e; scanf("%d",&e); while(e!=-111){ InsertBST(T,e); scanf("%d",&e); } return OK; } int main(){ SSTable ST; KeyType key; BiTree T=NULL,p=NULL; int locate; Init_Seq(ST); Creat_Seq(ST); printf("\n\n請輸入待查詢的數:"); scanf("%d",&key); if(Search_Seq(ST,key)) printf("\n\n順序查詢結果:%d在順序表中的第%d位\n",key,Search_Seq(ST,key)); else printf("\n順序查詢失敗 該資料不存在!\n"); locate = Search_Bin(ST,key); if(locate) printf("\n折半查詢結果:%d在有序表中的第%d位\n",key,locate); else printf("\n\n折半查詢失敗 該資料不存在!\n"); CreatBST(T); printf("\n請輸入待查詢的數:"); scanf("%d",&key); SearchBST(T,key,NULL,p); if(SearchBST(T,key,NULL,p)) printf("查詢成功!\n"); else printf("查詢失敗!\n"); }
//雜湊表的定義 建立 查詢 插入 以數值型元素為例 #include<stdio.h> #include<stdlib.h> #define EQ(a,b) a==b #define LT(a,b) a<b #define LQ(a,b) a<=b #define MAXSIZE 40 #define INCRESIZE 10 #define SUCCESS 1 #define UNSUCCESS 0 #define DUPLICATE -1 #define NULLKEY -111 typedef int KeyType; typedef int Status; typedef int ElemType; typedef struct{ ElemType *base;//資料元素儲存基址 動態分配陣列 int count;//當前資料元素的個數 int sizeindex;//hashsize[sizeindex]為當前容量 }HashTable; //初始化 Status InitHash(HashTable &H){ H.base = (ElemType *)malloc(MAXSIZE*sizeof(ElemType)); if(!H.base) exit(DUPLICATE); H.sizeindex = MAXSIZE; H.count = 0; for(int i=0;i<H.sizeindex;i++) H.base[i] = NULLKEY; return SUCCESS; } //構造雜湊函式 Status Hash(ElemType e,int &p){//根據函式計算儲存位置並賦給p p = e%19;//除留餘數法和平方取中法結合構造雜湊函式 return SUCCESS; } Status collision(HashTable H,int &p){//線性探測再散列表 int i; for(i=p+1;i<H.sizeindex;i++) if(H.base[i]==NULLKEY) p=i; if(i==H.sizeindex){ H.base = (ElemType *)realloc(H.base,(H.sizeindex+INCRESIZE)*sizeof(ElemType)); if(!H.base) exit(DUPLICATE); H.sizeindex += INCRESIZE; p = H.sizeindex; } return SUCCESS; } //在雜湊表裡查詢key 如果查詢成功 p儲存在表中的下標 返回成功 否則p指示插入位置 返回不成功,c用來計算衝突個數 Status SearchHash(HashTable H,KeyType key,int &p,int &c){ Hash(key,p);//用公式來計算他在數組裡的下標 //當該位置中填有記錄 並且與所查詢的關鍵字不相等的時候 while(H.base[p]!=NULLKEY&&H.base[p]!=key) { collision(H,p);//求得下一探測地址 } if(EQ(H.base[p],key)) return SUCCESS; return UNSUCCESS;//NULLKEY } //插入 Status InsertHash(HashTable &H,ElemType e){ int p,c=0;//c初始值為0在建表的時候可以用作參考 if(SearchHash(H,e,p,c)){ return UNSUCCESS; } else{ H.base[p] = e; H.count++; return SUCCESS; } } Status CreatHash(HashTable &H){ InitHash(H); ElemType a; printf("請構造雜湊表 輸入-111意為停止:\n"); scanf("%d",&a); while(a!=-111){ if(!InsertHash(H,a)) printf("已存在該關鍵字!\n"); scanf("%d ",&a); } return SUCCESS; } void Visitall(HashTable H){ int num = H.count; printf("\nresult:"); for(int i=0;i<H.sizeindex,num!=0;i++){ if(H.base[i]!=NULLKEY){ printf("%d ",H.base[i]); num--; } } } int main(){ ElemType num; int p,c; HashTable H; CreatHash(H); Visitall(H); printf("\n請輸入你要查詢的關鍵字:"); scanf("%d",&num); if(SearchHash(H,num,p,c)) printf("\n查詢成功!\n"); else printf("\n查詢失敗!\n"); return 0; }