一、实验目的
1、巩固二叉树的实现方法;
2、理解二叉排序树的递归插入和递归查找算法思想并用代码实现
3、理解哈希查找算法思想并用代码实现
三、实验内容及原理
涉及的知识点:
二叉树的表示,递归算法,二叉树的遍历,哈希查找算法
实验内容:
二叉排序、查找树:
1、用随机函数生成10个待排序元素;
2、利用二叉查找树输出升序序列;
3、利用同一棵二叉查找树输出降序序列;
4、写出查找的递归函数;注意:递归出口的处理要求:二叉排序树的程序填空:修改 “BiSearchTree.h” 文件中的myorder()函数,得到二叉排序树的降序序列,要求达到BiSearchTree.exe的执行效果。
哈希查找:
1、哈希表类的哈希函数采用除留余数法哈希函数;
2、解决哈希冲突的函数采用开放定址法中的线性探察法。
3、建立一个由10个数据元素组成的集合;
4、测试哈希表长度m=13和m=11两种情况下的哈希表,并查找其中的几个元素。
要求:哈希查找的程序填空:修改 “HashTable.h” 文件中的Find()函数;并编写测试程序。
四、实验过程原始数据记录
main.h
#include “BiSearchTree.hpp”
#include “HashTable.h”
void main(void)
{
test1();
test2();
}
BiSearchTree.hpp
#include “BTreeNode.hpp”
template
class BiSearchTree
{
private:
BTNode *root;
void PreOrder(BTNode *&t);
void InOrder(BTNode *&t);
void PostOrder(BTNode &t);
void myOrder(BTNode &t);
void Insert(BTNode&ptr,const T &item);
void Delete(BTNode&ptr,const T &item);
public:
BiSearchTree() {root=NULL;}
~BiSearchTree() {};
void PreOrder() {PreOrder(root);}
void InOrder() {InOrder(root);}
void PostOrder() {PostOrder(root);}
void myOrder() {myOrder(root);}
BTNode<T> *&GetRoot() {return root;}
BTNode<T> *&LeftChild(BTNode<T> *¤t)
{ return root!=NULL?current->Left():NULL;}
BTNode<T> *&RightChild(BTNode<T> *¤t)
{ return root!=NULL?current->Right():NULL;}
BTNode<T> *&Find(const T &item);
void Insert(const T &item) { Insert(GetRoot(),item);}
void Delete(const T &item) { Delete(GetRoot(),item);}
friend istream &operator>>(istream &in,BiSearchTree<T>*&tree);//
};
template
void BiSearchTree::PreOrder(BTNode *&t)
{
if(t!=NULL)
{
/Visit(t);/
t->Visit();
PreOrder(t->lc);
PreOrder(t->rc);
}
}
template
void BiSearchTree::InOrder(BTNode *&t)
{
if(t!=NULL)
{
InOrder(t->lc);
t->Visit();
InOrder(t->rc);
}
}
template
void BiSearchTree::PostOrder(BTNode *&t)
{
if(t!=NULL)
{
PostOrder(t->lc);
PostOrder(t->rc);
/Visit(t);/
t->Visit();
}
}
template
void BiSearchTree::myOrder(BTNode *&t)
{
// 输入您自己编写的语句
if (t != NULL)
{
myOrder(t->rc);
t->Visit();
myOrder(t->lc);
}
}
//查找的非递归算法
template
BTNode *&BiSearchTree::Find(const T &item)
{
if(root!=NULL)
{
BTNode *temp=root;
while(temp!=NULL)
{
if(temp->element==item) return temp;
if(temp->element<item) temp=temp->Right();
else temp=temp->Left();
}
}
return NULL;
}
template
void BiSearchTree::Insert(BTNode *&ptr,const T &item)
{
if(ptrNULL)
{
ptr=new BTNode(item);
if(ptrNULL)
{
cerr<<“空间不足!”<<endl;
exit(1);
}
}
else if(itemelement) Insert(ptr->Left(),item);
else if (item>ptr->element) Insert(ptr->Right(),item);
//否则就是item已在二叉排序树中,不做任何事
}
template
void BiSearchTree::Delete(BTNode *&ptr,const T &item)
{
BTNode *temp;
if(ptr!=NULL)
{
if(itemelement)Delete(ptr->Left(),item);
else if(item>ptr->element)Delete(ptr->Right(),item);
else if(ptr->Left()!=NULL&&ptr->Right()!=NULL)
{
BTNode<T> *min;
min=ptr->Right();
while(min->Left()!=NULL)min=min->Left();
ptr->element=min->element;
Delete(ptr->Right(),min->element);
}
else
{
temp=ptr;
if(ptr->Left()==NULL)ptr=ptr->Right();
else if(ptr->Right()==NULL)ptr=ptr->Left();
delete temp;
}
}
}
//二叉搜索树测试
void test1(void)
{
BiSearchTree searchTree;
time_t t;
srand((unsigned)time(&t));//随机
for (int i = 0; i < 10; i++) searchTree.Insert(rand() % 100);
cout << "二叉排序树升序列" << endl;
searchTree.InOrder();
cout << endl;
cout << "二叉排序树逆序列" << endl;
searchTree.myOrder();
cout << endl;
cout << "递归查找“66”:";
cout << myFind(searchTree.GetRoot(), 66)<<endl;
}
BTreeNode.hpp
using namespace std;
#include <iostream
#include “stdlib.h”
#include “time.h”
templateclass BiSearchTree;
templateclass BTNode;
template int myFind(BTNode*& ptr, const TT& item);
void test1(void);
template
class BTNode
{
friend class BiSearchTree;
friend int myFind<T>(BTNode<T> *&ptr,const T &item);
friend BTNode<T>* Find(BTNode<T>* &root,T item);
friend BTNode<T>* copytree(BTNode<T>* oldroot);
private:
T element;
BTNode<T> *lc,*rc;
public:
void Visit();
BTNode(){lc=rc=NULL;}
BTNode(const T e)
{
element=e;
lc=rc=NULL;
}
BTNode(const T e,BTNode<T> *l,BTNode<T> *r)
{
element=e;
lc=l;
rc=r;
}
BTNode(const BTNode<T> &a) // 拷贝构造函数
{
element=a->element;
lc=a->lc;
rc=a->rc;
}
BTNode<T>* &Left(void)
{ return lc; }
BTNode<T>* &Right(void)
{ return rc; }
};
template
void BTNode::Visit()
{
cout<element<<" ";
}
//查找的递归算法
template
int myFind(BTNode*& ptr, const TT& item)
{
if (ptr != NULL)
{
if (ptr->element == item) return 1;
if (ptr->element < item) return myFind(ptr->Right(), item);
else return myFind(ptr->Left(), item);
}
else return 0;
}
HashTable.h"
#pragma once
using namespace std;
#include “Datatype.h”
#include <iostream
enum KindOfItem {Empty, Active, Deleted};
struct HashItem
{
DataType data;
KindOfItem info;//数据块状态Empty, Active, Deleted
HashItem(KindOfItem i = Empty): info(i){}
HashItem(const DataType &D, KindOfItem i = Empty): data(D), info(i){}
int operator ==(HashItem &a)
{return data == a.data;}
int operator !=(HashItem &a)
{return data != a.data;}
};
class HashTable
{
private:
HashItem *ht; //哈希表数组
int TableSize; //哈希表的长度(即m)
int currentSize; //当前的表项个数
public:
HashTable(int m); //构造函数
~HashTable(void) //析构函数
{delete []ht;}
int Find(const DataType &x)const; //查找
int Insert(const DataType &x); //插入
int Delete(const DataType &x); //删除
int IsIn(const DataType &x) //是否已存在
{int i = Find(x); return i >= 0 ? 1: 0;}
DataType GetValue(int i)const //取数据元素
{return ht[i].data;}
};
//哈希表类实现
HashTable::HashTable(int m) //构造函数
{
TableSize = m; //置哈希表长度
ht = new HashItem[TableSize]; //申请动态数组空间
currentSize = 0; //置初始的当前表项个数
}
int HashTable::Find(const DataType &x)const //查找
{
//输入你自己编写的程序
int ho = x.key % 7;//除留余数作散列地址
while (ht[ho].info != Empty)
{
if (ht[ho].data.key == x.key)
{
if (ht[ho].info == Active)
return ho;//查找成功返回正数
else return -1;//Deleted
}
ho=(ho+1)% TableSize;//线性探测
}
return -1;//Empty
}
int HashTable::Insert(const DataType &x)
{
if (Find(x) >=0)return 0;
int i = x.key % 7;//除留余数作散列地址
while (ht[i].info == Active)
{
i = (i + 1) % TableSize;//线性探测
}
//数据元素x不存在且哈希表未满
ht[i].data = x; //数据元素赋值
ht[i].info = Active; //置活动标记
currentSize++; //当前表项个数加1
return 1; //返回插入成功状态
}
int HashTable::Delete(const DataType &x) //标记删除
{
int i = Find(x); //调用Find(x)
if(i >= 0)
{
ht[i].info = Deleted; //置删除标记
currentSize--; //当前表项个数减1
return 1; //返回删除成功状态
}
else return 0; //返回删除失败状态
}
//哈希表测试
void test2(void)
{
HashTable A(13);//hash表长13
for (int i = 0; i < 10; i++)//插入10项数据
{
A.Insert({ i,2 * i });
}
cout << "长度为13的哈希表 插入10项后:" << endl;
for (int i = 0; i < 13; i++)//打印表key
{
cout<<A.GetValue(i).key<<" ";
}
cout << endl;
//A.Delete({ 7,NULL });//删除key==7的项
cout << "哈希表中查找key==7的项:" ;
cout << A.Find({ 7,NULL }) << " ";//判断key==7的项是否存在
}
Datatype.h
typedef int KeyType;
typedef int datatype;
struct DataType
{
KeyType key;
datatype data;
DataType(void) {}
DataType(KeyType k) : key(k) {}
DataType(KeyType k, datatype d) : key(k),data(d) {}
int operator ==(const DataType& a)
{
return key == a.key;
}
int operator !=(const DataType& a)
{
return key != a.key;
}
};