實驗五 查詢的有關操作(資料結構)
實驗內容:
1.輸入一批有序的整形數值,利用折半插找的演算法實現查詢某數的過程。
2.利用一批資料(不超過13個數),構建一棵二叉排序樹,實現二叉排序樹的插入、刪除、查詢運算,並實現中序遍歷該樹。
3.將上面的資料利用長度為15的雜湊表儲存,輸出儲存後的雜湊表。雜湊函式採用key%13,用線性探測再雜湊解決衝突,設計並實現查詢運算。
*4.根據全班學生的姓名,用拉鍊法解決碰撞的方法構造一個散列表,選擇適當的雜湊函式,設計並實現插入、刪除和查詢演算法。
5.設計主函式,上機實現。
程式碼:
#include <iostream>
#include <string.h>
#include <algorithm>
#include <cstdio>
#include <cstdlib>
#define KeyType int
#define TABLESIZE 15
using namespace std;
int a[200],y=0;
KeyType dp[TABLESIZE];
typedef struct node{
KeyType key;
struct node *lchild,*rchild;
}BSTNode,*BSTree;
typedef struct elem{
int empt;
KeyType data;
}ElemType;
ElemType ht[TABLESIZE];
int Search(KeyType k){
int i=k%13,j=i;
while(ht[j].data!=-1&&ht[j].data!=k){
j=(j+1)%TABLESIZE;
if(j==i)
return -TABLESIZE;
}
if(ht[j].data==k)
return j;
else
return -j;
}
void InsertBST(BSTree *bt,KeyType key){
BSTree s;
if(*bt==NULL){
s=(BSTree)malloc(sizeof(BSTNode));
s->key=key;
s->lchild=NULL;
s->rchild=NULL;
*bt=s;
}
else if(key<(*bt)->key)
InsertBST(&((*bt)->lchild),key);
else
InsertBST(&((*bt)->rchild),key);
}
void CreateBST(BSTree *bt,int n){
KeyType key;
*bt=NULL;
int k=0;
while(n>0){
cin>>key;
InsertBST(bt,key);
n--;
}
}
BSTree SearchBST(BSTree bt,KeyType key){
if(!bt) return NULL;
if(bt->key==key)
return bt;
else if(bt->key>key)
return SearchBST(bt->lchild,key);
else
return SearchBST(bt->rchild,key);
}
void Inorder(BSTree bt){//中序
if(bt==NULL) return;
Inorder(bt->lchild);
cout<<bt->key<<" ";dp[y++]=bt->key;
Inorder(bt->rchild);
}
BSTree DelBST(BSTree bt,KeyType k){
BSTree p,f,s,q;
p=bt;f=NULL;
while(p){
if(p->key==k) break;
f=p;
if(p->key>k) p=p->lchild;
else p=p->rchild;
}
if(p==NULL) return bt;
if(p->lchild&&p->rchild){
q=p;
s=p->lchild;
while(s->rchild){
q=s;
s=s->rchild;
}
p->key=s->key;
if(q!=p) q->rchild=s->lchild;
else q->rchild=s->lchild;
free(s);
}
else{
if(!p->rchild){
q=p;
p=p->lchild;
}
else{
q=p;
p=p->rchild;
}
if(!f) bt=p;
else if(q==f->lchild) f->lchild=p;
else f->rchild=p;
free(q);
}
return bt;
}
int BinarySearch2(int length, int value)
{
if(NULL == a || 0 == length)
return -1;
int start = 0;
int endd = length -1;
int middle =0;
while(start <= endd){
middle = start + ((endd - start) >> 1);
if(value == a[middle])
return middle;
else if(value > a[middle]){
start = middle + 1;
}
else{
endd = middle -1;
}
}
return -1;
}
void Insert(KeyType k){
int i,adr;
adr = k%13;
if (ht[adr].data==-1 || ht[adr].data==-2) //x[j]可以直接放在雜湊表中
{
ht[adr].data=k;
ht[adr].empt=1;
}
else //發生衝突時,採用線性探查法解決衝突
{
i=1; //i記錄x[j]發生衝突的次數
do
{
adr = (adr+1)%13;
i++;
} while (ht[adr].data!=-1 && ht[adr].data!=-2);
ht[adr].data=k;
ht[adr].empt=i;
}
}
void cread(){
for(int i=0;i<TABLESIZE;i++){
//printf("%4d",i+1);
ht[i].empt=0;
ht[i].data=-1;
}
for(int i=0;i<y;i++)
Insert(dp[i]);
//cout<<endl;
}
void show(){
int i;
printf(" 雜湊表地址:\t");
for(i=0;i<15;i++)
printf("%4d",i);
printf("\n");
printf(" 雜湊表關鍵字:\t");
for(i=0;i<15;i++)
if(ht[i].data==-1 || ht[i].data==-2)
printf(" "); //輸出3個空格
else
printf("%4d",ht[i].data);
printf(" \n");
}
int main()
{
int n,x,log;
cout<<"請輸入序列總個數n:";
cin>>n;
cout<<"請輸入n個有序的整形數值:"<<endl;
for(int i=0;i<n;i++)
cin>>a[i];
//sort(a,a+n);
cout<<"請輸入要查詢的值:";
cin>>x;
log=BinarySearch2(n,x)+1;
if(log==0)
cout<<"查詢失敗"<<endl;
else
cout<<log<<endl;
int ch;
BSTree bst,p;
cout<<"請輸入二叉排序樹數值(<13)總個數n:";
cin>>ch;
cout<<"請輸入n個二叉排序樹的數值:"<<endl;
CreateBST(&bst,ch);
cout<<"中序遍歷二叉排序樹:"<<endl;
Inorder(bst);
cout<<endl<<"請輸入要查詢的二叉排序樹數值:";
cin>>ch;
p=SearchBST(bst,ch);
if(p!=NULL)
cout<<"查詢成功";
else cout<<"查詢失敗";
cout<<endl<<"請輸入要插入的二叉排序樹數值:";
cin>>ch;
InsertBST(&bst,ch);
Inorder(bst);
cout<<endl<<"請輸入要刪除的二叉排序樹數值:";
cin>>ch;
DelBST(bst,ch);y=0;
Inorder(bst);
cout<<endl;
cout<<" ********************** 雜湊表 **********************"<<endl;
cread();
show();
cout<<"請輸入要查詢的數值:";
cin>>ch;
cout<<Search(ch)<<endl;
return 0;
}
測試截圖: