查找算法

一、实验目的
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> *&current)
{ return root!=NULL?current->Left():NULL;}
BTNode<T> *&RightChild(BTNode<T> *&current)
{ 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(ptr
NULL)
{
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;
}
};

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值