//头文件(包括HosPital.h,TreeNode.h,Tree.h)
//HosPital.h
#ifndef HOSPARTNODE_H
#define HOSPARTNODE_H
#include<iostream>
#include<string>
using namespace std;
class HosPartNode{
private:
int num;
string name;
public:
HosPartNode(){
}
HosPartNode(string str, int number);
HosPartNode(const HosPartNode& str);
void setName(string str);
string getName()const;
int getNum()const;
friend ostream& operator<< (ostream& out, const HosPartNode& node);
};
void HosPartNode::setName(string str)
{
this->name = str;
}
HosPartNode::HosPartNode(string str, int number)
{
this->num = number;
this->name = str;
}
HosPartNode::HosPartNode(const HosPartNode& str)
{
this->name = str.getName();
this->num = str.getNum();
}
string HosPartNode::getName()const
{
return name;
}
int HosPartNode::getNum()const
{
return num;
}
ostream& operator<<(ostream& out, const HosPartNode& node)
{
out << node.getName() << ": " << node.getNum() << endl;
return out;
}
#endif // !HOSPARTNODE_H
//TreeNode.h
#ifndef TREENODE_H
#define TREENODE_H
#include"HosPartNode.h"
class TreeNode{
private:
HosPartNode value;
//左孩子
TreeNode* firstChild;
//右兄弟
TreeNode* lSibling;
public:
TreeNode()
{
this->firstChild = NULL;
this->lSibling = NULL;
}
TreeNode(string str)
{
value.setName(str);
}
TreeNode(const HosPartNode value, TreeNode* str, TreeNode* ptr);
HosPartNode getValue()const;
TreeNode* getChild()const;
TreeNode* getSibling()const;
void setValue(const HosPartNode& value);
void setChild(TreeNode* pointer);
void setSibling(TreeNode* pointer);
void InsertFirst(TreeNode* node);
void InsertNext(TreeNode* node);
void Print()const;
};
TreeNode::TreeNode(const HosPartNode value, TreeNode* str, TreeNode* ptr)
{
this->value = value;
this->firstChild = str;
this->lSibling = ptr;
}
HosPartNode TreeNode::getValue()const
{
return value;
}
TreeNode* TreeNode::getChild()const
{
return firstChild;
}
TreeNode* TreeNode::getSibling()const
{
return lSibling;
}
void TreeNode::setValue(const HosPartNode& node)
{
this->value = node;
}
void TreeNode::setChild(TreeNode* pointer)
{
this->firstChild = pointer;
}
void TreeNode::setSibling(TreeNode* pointer)
{
this->lSibling = pointer;
}
void TreeNode::InsertFirst(TreeNode* node)
{
//在根节点下以左孩子的身份插入节点node
this->firstChild = node;
}
void TreeNode::InsertNext(TreeNode* node)
{
//插入节点作为当前节点的右兄弟存在
this->lSibling = node;
}
void TreeNode::Print()const
{
TreeNode* str = this->getChild();
cout << str->getValue();
str = str->getSibling();
while (str)
{
cout << str->getValue();
str = str->getSibling();
}
cout << endl;
}
#endif // !TREENODE_H
//Tree.h
#ifndef TREE_H
#define TREE_H
#include"TreeNode.h"
#include<queue>
#include<string>
#include<stack>
using namespace std;
class Tree{
private:
TreeNode* root;
public:
Tree();
~Tree();
bool empty()const;
TreeNode* getRoot()const;
TreeNode* getParent(const string str)const;
TreeNode* Find(const string current)const;
void Insert(string parent,HosPartNode rootValue);
//遍历的方式三种:广度,先根,后根
void RootFirstTraverse()const;
void RootLastTraverse()const;
void WithTraverse()const;
int Count(string parent, string child)const;
};
Tree::Tree()
{
this->root = NULL;
}
Tree::~Tree()
{
if (root == NULL)
{
cout << "树为空" << endl;
exit(true);
}
queue<TreeNode*>node;
node.push(root);
while (!node.empty())
{
root = node.front();
node.pop();
if (root->getChild())
node.push(root->getChild());
if (root->getSibling())
node.push(root->getSibling());
delete root;
}
this->root = NULL;
}
bool Tree::empty()const
{
if (this->root == NULL)
{
return true;
}
return false;
}
TreeNode* Tree::getRoot()const
{
return this->root;
}
TreeNode* Tree::getParent(const string str)const
{
//利用遍历规则查找当前节点的父亲节点
TreeNode* current = this->Find(str);
if (current == NULL)
{
cout << "没找到节点" << endl;
return NULL;
}
queue<TreeNode*>node;
//parent记录父亲节点
TreeNode* parent = NULL;
//pointer为当前节点
TreeNode* pointer = this->root;
node.push(pointer);
while (!node.empty())
{
pointer = node.front();
node.pop();
//将当前节点的信息给parnet
parent = pointer;
//如果当前节点的孩子不为空,则将孩子节点的信息给当前节点
if ((pointer = pointer->getChild()) != NULL)
{
while (pointer != NULL)
{
//如果当前节点不为空,而且满足pointer==current,则返回parent
if (pointer == current)
{
return parent;
}
//否则将当前节点入队列
node.push(pointer);
pointer = pointer->getSibling();
}
}
}
return NULL;
}
TreeNode* Tree::Find(const string current)const
{
if (this->empty())
{
cout << "树为空,不允许查找行为" << endl;
exit(true);
}
queue<TreeNode*>node;
TreeNode* str = this->root;
node.push(str);
while (!node.empty())
{
//开始遍历树,该树的存储结构是左孩子/右兄弟
//所以在遍历时要注意遍历顺序
str = node.front();
node.pop();
//如果找到要查找的节点信息,则返回该节点
if (str->getValue().getName() == current)
{
return str;
}
//如果该节点的孩子节点不为空,则将孩子节点如队列
//并将str指针指向孩子节点
if (str->getChild())
{
node.push(str = str->getChild());
}
//开始查找右兄弟节点
while (str)
{
//当右兄弟节点不为空时,则将该节点入队列,并将该str指针指向右孩子指针
if (str->getSibling())
{
node.push(str = str->getSibling());
}
else
{
break;
}
}
}
return NULL;
}
void Tree::Insert(string parent, HosPartNode rootValue)
{
//该函数的意思是给出父节点的信息,在父节点之后插入节点
//如果该树为空,则生成以parent为信息的根节点,并为根节点添加以rootValue为信息的节点
if (this->empty())
{
this->root = new TreeNode(parent);
this->root->setChild(new TreeNode(rootValue, NULL, NULL));
}
else
{
//如果树不为空,且找到以parent为信息的节点,就以该节点为父节点插入信息
TreeNode* str = this->Find(parent);
if (str == NULL)
{
cout << "没找到节点" << endl;
return;
}
if (str->getChild() == NULL)
{
//如果该节点的孩子为空,则生成该节点的孩子节点
str->InsertFirst(new TreeNode(rootValue,NULL,NULL));
}
else
{
str = str->getChild();
while (str->getSibling() != NULL)
{
//当str的右兄弟节点为空时,停止循环,并生成节点
str = str->getSibling();
}
str->InsertNext(new TreeNode(rootValue, NULL, NULL));
}
}
}
void Tree::RootFirstTraverse()const
{
if (this->empty())
{
cout << "树为空" << endl;
return;
}
TreeNode* str = this->root;
stack<TreeNode*>node;
while (!node.empty() || str)
{
if (str)
{
cout << str->getValue();
if (str->getSibling())
{
//如果该节点存在有兄弟节点,就将右兄弟节点入栈
node.push(str->getSibling());
}
//之后继续访问左子树
str = str->getChild();
}
else
{
//如果左子树访问完毕,则开始访问右子树
str = node.top();
node.pop();
}
}
}
void Tree::RootLastTraverse()const
{
//该遍历的顺序是左孩子,右兄弟,根
if (this->empty())
{
cout << "树为空" << endl;
return;
}
TreeNode* str = this->root;
TreeNode* pre = this->root;
//该函数是非递归遍历的方法,利用堆栈的先进后出原理
stack<TreeNode*>node;
while (str)
{
for ( ; str->getChild() != NULL; str = str->getChild())
{
//找到最左的左孩子
node.push(str);
}
//该循环特值为根节点时的情况
while (str != NULL && (str->getSibling() == NULL || str->getSibling() == pre))
{
//当前节点存在,没有右兄弟或者右兄弟已经被访问过,则访问当前节点
cout << str->getValue();
//记录刚被访问过的节点
pre = str;
if (node.empty())
{
return;
}
str = node.top();
node.pop();
}
node.push(str);
str = str->getSibling();
}
}
void Tree::WithTraverse()const
{
if (this->empty())
{
cout << "树为空" << endl;
return;
}
TreeNode* str = this->root;
queue<TreeNode*>node;
node.push(str);
while (!node.empty())
{
//该遍历函数的遍历一层一层的遍历
str = node.front();
node.pop();
cout << str->getValue();
if (str->getChild())
node.push(str->getChild());
while (str->getSibling())
{
node.push(str->getSibling());
str = str->getSibling();
}
}
}
int Tree::Count(string parent, string child)const
{
TreeNode* str = this->Find(parent);
TreeNode* ptr = this->Find(child);
if (str == NULL || ptr == NULL)
{
return 0;
}
int num = 1;
TreeNode* temp = NULL;
while (ptr != str)
{
temp = this->getParent(ptr->getValue().getName());
if (temp == NULL)
{
return 0;
}
num *= ptr->getValue().getNum();
ptr = temp;
}
return num;
}
#endif // !TREE_H
//主函数
#include"Tree.h"
int main(int argc, char argv[])
{
Tree Hospital;
Hospital.Insert("医院", HosPartNode("楼层", 10));
Hospital.Insert("楼层", HosPartNode("中央大厅", 1));
Hospital.Insert("楼层", HosPartNode("配楼", 4));
Hospital.Insert("中央大厅", HosPartNode("电视", 1));
Hospital.Insert("中央大厅", HosPartNode("沙发", 2));
Hospital.Insert("配楼", HosPartNode("长走廊", 2));
Hospital.Insert("配楼", HosPartNode("走廊连接", 1));
Hospital.Insert("长走廊", HosPartNode("病房", 21));
Hospital.Insert("走廊连接", HosPartNode("库房", 5));
Hospital.Insert("病房", HosPartNode("卫生间", 1));
Hospital.Insert("病房", HosPartNode("插座", 4));
Hospital.Insert("病房", HosPartNode("病床", 2));
Hospital.Insert("卫生间", HosPartNode("洗面盆", 1));
Hospital.Insert("卫生间", HosPartNode("座便器", 1));
Hospital.Insert("插座", HosPartNode("插口", 2));
Hospital.Insert("插座", HosPartNode("面板", 1));
Hospital.RootFirstTraverse();
Hospital.WithTraverse();
cout << Hospital.Count("病房", "插口") << endl;
cout << Hospital.Find("面板")->getValue() << endl;
return 0;
}
医院管理系统(实现功能:浏览医院的整体结构,给定任意节点输出该节点信息就子节点信息,计算在给出点之间的“病房的数量”)
最新推荐文章于 2022-11-28 17:37:59 发布