医院管理系统(实现功能:浏览医院的整体结构,给定任意节点输出该节点信息就子节点信息,计算在给出点之间的“病房的数量”)

//头文件(包括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;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值