实验五
实验名称:查找的有关操作 | |
实验室名称:丹青909 | 实验台号:14 |
学生姓名: 陈佳龙 | 专业班级: 2015级1班 |
指导教师:于慧伶 | 实验日期:2017-6-12 |
一、实验目的
⑴掌握折半查找算法的思想及程序实现。
⑵掌握二叉排序树的查找、插入、删除、建立算法的思想及程序实现。
⑶掌握散列存储结构的思想,能选择合适散列函数,实现不同冲突处理方法的散列表的查找、建立。
二、实验仪器及环境:
PC计算机;windows XP操作系统、Visual C++6.0、CodeBlocks
三、实验内容及结果(按照具体实验题目,按照如下格式书写)
1、
#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;
}
7、
四、实验心得体会:(包括遇到的问题及解决办法)
折半查找的条件是数组有序,时间复杂度为log2(n),二叉排序树的中序遍历输出结果是有序的,哈希表的线性探测法解决冲突,探测次数。
五、指导教师意见及成绩
签名:
年 月 日