实验题目 二叉树的应用
实验目的
- 学习并掌握二叉树数据结构及实现方法,掌握树的遍历方法。
- 熟练掌握二叉检索树(BST)的基本操作及其应用。
实验内容:
1.利用BST实现一个城市数据库:每个数据库结点包括城市名称和以整数x与y表示的城市坐标,根据城市名称组织该BST;
2.在该数据库上实现按城市名称进行的插入、删除和检索;
3.打印出以指定字母打头的所有城市记录;
4.打印出与指定点的距离在给定值之内的所有城市记录;
测试样例:
输入:
4
chongqing 1 1
chengdu 1 2
shenyang 2 2
changchun 2 3
1 shanghai 2 3
0 changchun
0 shenyang
1 beijing 2 2
2
c
0 0 3
输出:
beijing
chengdu
chongqing
shanghai
chengdu 1 2
chongqing 1 1
beijing 2 2
chengdu 1 2
chongqing 1 1
源代码
#include <iostream>
#include<string.h>
#include<math.h>
using namespace std;
class City{//City类,成员有城市名,坐标(x,y)
public:
string name;
int x;
int y;
City()
{x=0;
y=0;}
City(string Name,int X,int Y){
name=Name;
x=X;
y=Y;
}
};
bool operator >(string s1 ,string s2){//string型城市名比较大小
if(s1[0]-'a'>s2[0]-'a')
return true;
else if(s1[0]-'a'==s2[0]-'a')
{
for(int i=1;i<s1.length();i++)
{
if(s1[i]-'a'>s2[i]-'a')
return true;
else if(s1[i]-'a'<s2[i]-'a')
return false;
else if(i==s1.length()-1)
return false;
}
}
else if(s1[0]-'a'<s2[0]-'a')
return false;
}
bool operator <(string s1,string s2){//string型城市名比较大小
if(s1[0]-'a'<s2[0]-'a')
return true;
else if(s1[0]-'a'==s2[0]-'a')
{
for(int i=1;i<s1.length();i++)
{
if(s1[i]-'a'<s2[i]-'a')
return true;
else if(s1[i]-'a'>s2[i]-'a')
return false;
else if(i==s1.length()-1)
return false;
}
}
else if(s1[0]-'a'>s2[0]-'a')
return false;
}
bool operator ==(string s1,char c){//判断是s1首字母是否为指定字母
if(s1[0]==c)
return true;
else
return false;
}
template <typename Key, typename E>
class BSTNode
{ private:
Key k;
E it;
BSTNode* lc;
BSTNode* rc;
public:
BSTNode(Key K, E e, BSTNode* l =NULL, BSTNode* r =NULL)
{ k = K; it = e; lc = l; rc = r;}
BSTNode()
{ lc = rc = NULL; }
E& element()
{ return it; }
void setElement(const E& e)
{ it = e; }
Key& key() {
return k; }
void setKey(const Key& K) {
k = K; }
inline BSTNode* left() const
{ return lc; }
void setLeft(BSTNode<Key,E>* b)
{ lc = b; }
inline BSTNode* right() const
{ return rc; }
void setRight(BSTNode<Key,E>* b)
{ rc = b; }
/* isLeaf() {
return (lc == NULL) && (rc == NULL); }*/
};
template <typename Key, typename E> class BST//: public Dictionary<Key,E>
{ private:
BSTNode<Key,E>* root;
int nodecount;
void clearhelp(BSTNode<Key, E>*);
BSTNode<Key,E>* inserthelp(BSTNode<Key, E>*, const Key&, const E&);
BSTNode<Key,E>* deletemin(BSTNode<Key, E>*);
BSTNode<Key,E>* getmin(BSTNode<Key, E>*);
void helpprint1(BSTNode<string, City>* sroot , char c);
void helpprint2(BSTNode<string, City>* sroot ,int x0,int y0,int d);
BSTNode<Key,E>* removehelp(BSTNode<Key, E>*, const Key&);
E findhelp(BSTNode<Key, E>*, const Key&) const;
void printhelp(BSTNode<Key, E>*) const;
public:
BST() {
root = NULL;
nodecount = 0;
}
~BST() {
clearhelp(root); }
void clear()
{ clearhelp(root);
root = NULL;
nodecount = 0; }
void insert(const Key& k, const E& e)
{ root = inserthelp(root, k, e);
nodecount++; }
E remove(const Key& k) {
E temp = findhelp(root, k);
root = removehelp(root, k);
nodecount--; //}
return temp; }
E removeAny() {
if (root != NULL) {
E temp = root->element();
root = removehelp(root, root->key());
nodecount--;
return temp;}
else return NULL;
}
E find(const Key& k) const
{
return findhelp(root, k);
}
int size() {
return nodecount;
}
void print1(char c){ //打印指定字母开头的城市 城市名 x y
if(root!=NULL)
helpprint1(root,c);
}
void print2(int x0,int y0,int d){//打印指定点在给定距离内的所有城市 城市名 x y
if(root!=NULL)
{
helpprint2(root,x0,y0,d);
}
}
void print() const { //中序遍历并打印,城市名字
if (root == NULL)
cout << "The BST is empty.\n";
else printhelp(root);
}
};
template <typename Key, typename E>
E BST<Key, E>::findhelp(BSTNode<Key, E>* root, const Key& k) const
{
if (k< root->key())
return findhelp(root->left(), k); // Check left
else if (k> root->key())
return findhelp(root->right(), k); // Check right
else
{ // if(k==root->key())
return root->element();
// else
// return findhelp(root->left(), k);
}
}
template <typename Key, typename E>
BSTNode<Key, E>* BST<Key, E>:: getmin(BSTNode<Key, E>* rt)
{ if (rt->left() == NULL)
return rt;
else
return getmin(rt->left());
}
template <typename Key, typename E>
BSTNode<Key, E>* BST<Key, E>:: deletemin(BSTNode<Key, E>* rt)
{ if (rt->left() == NULL) // Found min
return rt->right();
else { // Continue
rt->setLeft(deletemin(rt->left()));
return rt; }
}
template <typename Key, typename E>
void BST<Key,E>:: helpprint2(BSTNode<string, City>* sroot ,int x0,int y0,int d)
{if(sroot!=NULL){
helpprint2(sroot->left(),x0,y0,d);
City scity=sroot->element();
if((scity.x-x0)*(scity.x-x0)+(scity.y-y0)*(scity.y-y0)<d*d||(scity.x-x0)*(scity.x-x0)+(scity.y-y0)*(scity.y-y0)==d*d)
cout<<scity.name<<' '<<scity.x<<' '<<scity.y<<endl;
helpprint2(sroot->right(),x0,y0,d);
}
}
template <typename Key, typename E>
void BST<Key,E>:: helpprint1(BSTNode<string, City>* sroot ,char c){
if(sroot!=NULL)
{ helpprint1(sroot->left(),c);
if(sroot->key()==c)
{ City scity=sroot->element();
cout<<scity.name<<' '<<scity.x<<' '<<scity.y<<endl;
}
helpprint1(sroot->right(),c);
}
}
template <typename Key, typename E>
void BST<Key, E>:: clearhelp(BSTNode<Key, E>* root)
{ if (root == NULL)
return;
clearhelp(root->left());
clearhelp(root->right());
delete root; }
template <typename Key, typename E>
void BST<Key, E>:: printhelp(BSTNode<Key, E>* root) const
{ if (root == NULL) return; // Empty tree
printhelp(root->left()); // Do left subtree
cout << root->key() << "\n"; // Print node value
printhelp(root->right()); // Do right subtree
}
template <typename Key, typename E>
BSTNode<Key, E>* BST<Key, E>::inserthelp( BSTNode<Key, E>* root, const Key& k, const E& it)
{ if (root == NULL) // Empty tree: create node
return new BSTNode<Key, E>(k, it, NULL, NULL);
if (k < root->key())
root->setLeft(inserthelp(root->left(), k, it));
else root->setRight(inserthelp(root->right(), k, it));
return root; // Return tree with node inserted
}
template <typename Key, typename E>
BSTNode<Key, E>* BST<Key, E>:: removehelp(BSTNode<Key, E>* rt, const Key& k)
{ if (rt == NULL) return NULL; // k is not in tree
else if (k < rt->key())
rt->setLeft(removehelp(rt->left(), k));
else if (k > rt->key())
rt->setRight(removehelp(rt->right(), k));
else { // Found: remove it
if(k==rt->key())
{
BSTNode<Key, E>* temp = rt;
if (rt->left() == NULL) { // Only a right child
rt = rt->right(); // so point to right
delete temp; }
else if (rt->right() == NULL) { // Only a left child
rt = rt->left(); // so point to left
delete temp; }
else { // Both children are non-empty
BSTNode<Key, E>* temp = getmin(rt->right());
rt->setElement(temp->element());
rt->setKey(temp->key());
rt->setRight(deletemin(rt->right()));
delete temp; }
}
else
rt->setLeft(removehelp(rt->left(), k));
}
return rt;
}
int main()
{int m;
char a;
int n;
int i;
string cityname;
int x0;
int y0;
int d;
BST<string,City> bstcity;
City city;
cin>>m;
for(i=0;i<m;i++)
{cin>>city.name>>city.x>>city.y;
bstcity.insert(city.name,city);
}
cin>>n;
while(n!=2)
{
if(n==0)
{
cin>>cityname;
bstcity.remove(cityname);
}
if(n==1)
{
cin>>city.name>>city.x>>city.y;
bstcity.insert(city.name,city);
}
cin>>n;
}
//中序遍历并打印,城市名字
bstcity.print();
//打印指定字母开头的城市 城市名 x y
cin>>a;
bstcity.print1(a);
//打印指定点在给定距离内的所有城市 城市名 x y
cin>>x0>>y0>>d;
bstcity.print2(x0,y0,d);
return 0;
}