一、 实验目的
1. 熟悉线性表、二叉排序树和散列表的查找
2. 能够编写一些查找的算法
二、 实验内容
1 . 18个记录的关键字为22、12、13、8、9、20、33、42、44、38、24、48、60、58、74、49、86、53,编写分块查找的算法进行查找。
//fenkuai.h
//分块查找
#include<iostream>
using namespace std;
struct table //需要查找的表
{
int r[100];
int length;
};
struct indexitem //索引表的一个元素
{
int key;
int stadr;
};
struct indextable //索引表
{
indexitem elem[51];
int length;
};
void create(table &st,indextable &id,int n,int m)//创建查找的表和索引表,查找的表长度n,索引表长度m
{
int i;
cout<<"请输入查找的表"<<endl;
st.length=n;
for(i=0;i<n;i++)cin>>st.r[i];
cout<<"请输入索引表"<<endl;
id.length=m;
for(i=0;i<m;i++)cin>>id.elem[i].key>>id.elem[i].stadr;
cout<<endl;
}
int search(table &st,indextable &id,int k)//k是要查找的数字,返回他的位置
{
int low,high,mid;
int p=-1;
int s,t;
low=0;
high=id.length-1;
while(low<=high&&p<0) //使用折半法查找在哪一块
{
mid=(low+high)/2;
if(k>id.elem[mid-1].key && k<id.elem[mid].key)
p=mid;
else
{
if(k<id.elem[mid].key)
high=mid-1;
else if(k>id.elem[mid].key)
low=mid+1;
else
p=mid;
}
}
s=id.elem[p].stadr; //确定在哪一块之后顺序查找
if(p==id.length-1)
t=st.length;
else
t=id.elem[p+1].stadr-1;
while(k!=st.r[s]&&s<=t)
s++;
if(s>t)
return 0;
else
return s;
}
//main.cpp
#include<iostream>
#include"fenkuai.h"
using namespace std;
int main()
{
int ans;
int cha;
table st;
indextable id;
cout<<"请输入要查找的数"<<endl;
cin>>cha;
create(st,id,18,3);
ans=search(st,id,cha);
cout<<cha<<"的位置是"<<ans+1<<endl;
return 0;
}
2 . 编写一个判别给定的二叉树是否为二叉排序树的算法,设二叉树以二叉链表存储表示,结点的数据域只存放正整数。
//bitree.h
//本头文件包含binode类和二叉链表bitree类
#include<iostream>
using namespace std;
template<class T>
struct binode
{
T data; //存储数据
binode<T> * lchild,* rchild; //左孩子,右孩子
};
template<class T>
class bitree
{
private:
binode<T> * root; //指向根节点的头指针
int allsum;//节点总数
int yesum;//叶子节点总数
int a;
binode<T> * creat(binode<T> *bt); //构造函数调用
void release(binode<T> *bt); //析构函数调用
void preorder(binode<T> *bt); //前序遍历函数调用
void inorder(binode<T> *bt); //中序遍历函数调用
void postorder(binode<T> *bt);//后序遍历函数调用
void exchange(binode<T> *bt);//交换左右子树,实验五第一问
int sum(binode<T> *bt);//节点总数,实验五第二问
int ysum(binode<T> *bt);//叶子节点总数,实验五第二问
int px(binode<T> *bt);
public:
bitree(){root=creat(root);} //构造函数
~bitree(){release(root);} //析构函数
void preorder(){preorder(root);} //前序遍历函数
void inorder(){inorder(root);} //中序遍历函数
void postorder(){postorder(root);} //后序遍历函数
void exchange(){exchange(root);}//交换左右子树
int sum(){allsum=sum(root);return allsum;}//节点总数
int ysum(){yesum=ysum(root);return yesum;}//叶子节点总数
int px(){a=px(root);return a;} //判断是否是二叉排序树,实验8第二问
};
template<class T>
binode<T> * bitree<T>::creat(binode<T> *bt)//建立二叉链表
{
T ch;
cin>>ch;
if(ch==-1)bt=NULL;
else
{
bt=new binode<T>;
bt->data=ch;
bt->lchild=creat(bt->lchild);
bt->rchild=creat(bt->rchild);
}
return bt;
}
template<class T>
void bitree<T>::preorder(binode<T> *bt)//前序遍历递归
{
if(bt==NULL)return;
else
{
cout<<bt->data;//先输出根节点
preorder(bt->lchild);//前序遍历左子树
preorder(bt->rchild);//前序遍历左子树
}
}
template<class T>
void bitree<T>::inorder(binode<T> *bt)//中序遍历递归
{
if(bt==NULL)return;
else
{
inorder(bt->lchild);//中序遍历左子树
cout<<bt->data;//输出根节点
inorder(bt->rchild);//中序遍历右子树
}
}
template<class T>
void bitree<T>::postorder(binode<T> *bt)//后序遍历递归
{
if(bt==NULL)return;
else
{
postorder(bt->lchild);//后序遍历左子树
postorder(bt->rchild);//后序遍历右子树
cout<<bt->data;//输出根节点
}
}
template<class T>
void bitree<T>::release(binode<T> *bt) //释放二叉链表
{
if(bt!=NULL)
{
release(bt->lchild);//释放左子树
release(bt->rchild);//释放右子树
delete bt;//删除根节点
}
}
template<class T>
void bitree<T>::exchange(binode<T> *bt) //交换
{
binode<T> *temp;
temp=new binode<T>;
if((bt->lchild!=NULL)&&(bt->rchild!=NULL))//左右非空
{
if(bt->lchild->data>bt->rchild->data)//左边的数大于右边
{
temp=bt->lchild;
bt->lchild=bt->rchild;//交换
bt->rchild=temp;
}
exchange(bt->lchild);//检查左子树
exchange(bt->rchild);//检查右子树
}
}
template<class T>
int bitree<T>::sum(binode<T> *bt)//节点总数
{
int count=0;
count++;//节点数量加1
if(bt->lchild!=NULL)//左边非空,检查左边
{
count+=sum(bt->lchild);
}
if(bt->rchild!=NULL)//右边非空,检查右边
{
count+=sum(bt->rchild);
}
return count;
}
template<class T>
int bitree<T>::ysum(binode<T> *bt)//叶子节点总数
{
int countt=0;
if((bt->lchild==NULL)&&(bt->rchild==NULL))//当左右都空,数量加1
countt++;
if(bt->lchild!=NULL)//左边非空,检查左边
{
countt+=ysum(bt->lchild);
}
if(bt->rchild!=NULL)//右边非空,检查右边
{
countt+=ysum(bt->rchild);
}
return countt;
}
template<class T>
int bitree<T>::px(binode<T> *bt)//判断是否是二叉排序树
{
int ans=0;
if(bt->lchild!=NULL)
{
if(bt->lchild->data>bt->data)//如果左孩子大于根节点,说明不是二叉排序树
{
ans++;
return ans;
}
ans+=px(bt->lchild);
}
if(bt->rchild!=NULL)
{
if(bt->rchild->data<bt->data)//如果右孩子小于根节点,说明不是二叉排序树
{
ans++;
return ans;
}
ans+=px(bt->rchild);
}
return ans;//如果是二叉排序树,返回值为0
}
#include<iostream>
#include"bitree.h"
using namespace std;
int main()
{
bitree<int> a;
int m=0; //实验8.2 判断是否是二叉排序树
m=a.px();
if(m==0)cout<<"是二叉排序树"<<endl;
else cout<<"不是二叉排序树"<<endl;
return 0;
}