数据结构实验2

#include <iostream>
#include<list>
#include<vector>
#include<algorithm>
using namespace std;

template<class T>
struct BTNode
{
public:
	T element;
	BTNode* leftchild;
	BTNode* rightchild;


	BTNode() {leftchild = rightchild = NULL;}
	BTNode(T x, BTNode*a, BTNode*b)
	{
		leftchild = a;
		rightchild = b;
		element = x;
	}
	~BTNode(){};
	BTNode(T x) { element = x; leftchild = NULL; rightchild = NULL; }

	BTNode<T> operator=(BTNode<T> x)
	{
		element = x.element;
		leftchild = x.leftchild;
		rightchild = x.rightchild;
		return *this;
	}
};

template<class T>
class BT
{
public:
	BT() { root = NULL; treesize = 0; trans=0;}
	BT(int num){
		root=NULL;
		treesize=num;
		trans=0;
	}
	~BT() { erase(root); }

	BTNode<T>* myroot() { return root; };
	void initial(int num);
	bool empty()const { return treesize == 0; }
	int size() { return treesize; }
	void preorder(BTNode<T>* t);
	void out_xor(BTNode<T>* t);
	void inorder(BTNode<T>* t);
	void postorder(BTNode<T>* t);
	void levelorder(BTNode<T>* t);
	void fun5();
	void fun6();
	BTNode<T>* find(int node,BTNode<T>* t);

	int calnum(BTNode<T>* t);
	int calhei(BTNode<T>* t);

	void visit(BTNode<T>* t) { cout << t->element << " "; }
	void erase(BTNode<T>* t)
	{
		
		if (t != NULL)
		{
			erase(t->leftchild);
			erase(t->rightchild);
			delete t;
		}
		root = NULL;
		treesize = 0;
	}

	BTNode<T>* root;
	int treesize;
	int ans;
	bool trans;
};
/*-----------------------------------------------------*/

struct treenode
{
	int element;
	int parent;
	vector<int> children;
	
	treenode(){};
	treenode(int ele,int par){element=ele;parent=par;};
	
};

template<class T>
class forest
{
public:
	forest()
	{
		forestsize=0;
		treenum=0;
		fore.resize(5005);	
	};
	~forest()
	{
		from_forest.erase(from_forest.root);
	};
	void initial(int num1,int num2);
	void out_xor(int rootnode);
	void to_bt();
	void construct(BTNode<T>* a,int b);
	void out_test(int);
	void fun1();
	void fun2();
	void fun3();
	void fun4();
	void fun5(){from_forest.fun5();}
	void fun6();
		
	vector<treenode> fore;
	int treeroot[110];//用于保存根节点下标,从而找到根节点; 
	int forestsize;
	int treenum;	
	int ans;
	bool trans;
	BT<T> from_forest;
};
/*-------------------------------------------*/



/*-----------------------------------------------------*/
/*-----------------------------------------------------*/
//类btree的ADT 
template<class T>
class btree
{
public:
	btree() { root = NULL; treesize = 0; trans=0;}
	btree(int num){
		root=NULL;
		treesize=num;
		trans=0;
	}
	~btree() { erase(root); }

	BTNode<T>* myroot() { return root; };
	void initial(int num);
	bool empty()const { return treesize == 0; }
	int size() { return treesize; }
	void preorder(BTNode<T>* t);
	void out_xor(BTNode<T>* t)
	{
		if (t != NULL)
	{
		ans^=(t->element);
		out_xor(t->leftchild);
		out_xor(t->rightchild);
	}
	};
	void inorder(BTNode<T>* t);
	void postorder(BTNode<T>* t);
	void levelorder(BTNode<T>* t);
	void to_forest();
	void construct_for(BTNode<T>*);
	void fun1(){
		from_bt.fun1();
	};
	void fun2()
	{
		from_bt.fun2();
	};
	void fun3()
	{
		from_bt.fun3();
	};
	void fun4()
	{
		to_forest();
	};
	void fun5()
	{
		int pos,father,node;
		cin>>pos>>father>>node;
		BTNode<T>* f=find(father,root);
		BTNode<T>* _node=new BTNode<T>(node);
		if(pos==0)
			f->rightchild=_node;
		else f->leftchild=_node;
		treesize++;
	};
	void fun6()
	{
		if(trans==0)
		{
			ans=0;
			out_xor(root);
			cout<<ans<<endl;
		}
		else if(trans==1)
		{
			from_bt.trans=0;
			from_bt.fun6();		
		}
	};
	BTNode<T>* find(int node,BTNode<T>* t);

	int calnum(BTNode<T>* t);
	int calhei(BTNode<T>* t);

	void visit(BTNode<T>* t) { cout << t->element << " "; }
	void erase(BTNode<T>* t)
	{
		
		if (t != NULL)
		{
			erase(t->leftchild);
			erase(t->rightchild);
			delete t;
		}
		root = NULL;
		treesize = 0;
	}

	BTNode<T>* root;
	int treesize;
	int ans;
	bool trans;
	forest<int> from_bt;
};
/*-----------------------------------------------------*/
/*-----------------------------------------------------*/

template<class T>
void btree<T>::levelorder(BTNode<T>* t)
{
	list<BTNode<T>* > q;
	while (t != NULL)
	{
		BT<T>::visit(t);
		if (t->leftchild != NULL)
			q.push_back(t->leftchild);
		if (t->rightchild != NULL)
			q.push_back(t->rightchild);

		if (!q.empty())
			t = q.front();
		else return;
		q.pop_front();
	}
}

template<class T>
BTNode<T>* btree<T>::find(int node,BTNode<T>* t)
{
	list<BTNode<T>* > q;
	while (t != NULL)
	{
		if(t->element==node)
		return t;
		if (t->leftchild != NULL)
			q.push_back(t->leftchild);
		if (t->rightchild != NULL)
			q.push_back(t->rightchild);

		if (!q.empty())
			t = q.front();
		else return NULL;
		q.pop_front();
	}
}

template<class T>
void btree<T>::initial(int num)
{
	cout<<"请输入二叉树中各初始节点:"<<endl;
	treesize = num;
	trans=0;
	int node_root;
	cin>>node_root;
	BTNode<T> **temp = new BTNode<T>*[treesize+1];
	for (int i = 1; i <= treesize; ++i)
		temp[i] = new BTNode<T>(i);
	root = temp[node_root];

	int A, left, right;
	for (int j = 1; j <= treesize; ++j)
	{
		cin >> A>> left >> right;
		if (left != -1)
			temp[j]->leftchild = temp[left];
		else temp[j]->leftchild = NULL;
		if (right != -1)
			temp[j]->rightchild = temp[right];
		else temp[j]->rightchild = NULL;
	}
	delete []temp;
	cout<<"二叉树初始完毕!"<<endl;
}

template<class T>
void btree<T>::to_forest()
{
	trans=1;
	vector<BTNode<T>*> root_node;
	BTNode<T>* t=root,*x=NULL;
	from_bt.treenum=0;
	while(t!=NULL)
	{
		root_node.push_back(t);
		from_bt.treeroot[from_bt.treenum++]=t->element;
		x=t;
		t=t->rightchild;
		x->rightchild=NULL;
	}
	//依次将每棵二叉树转化为树
	for(int i=0;i<from_bt.treenum;++i)
	{
		//cout<<"TEST: ";
		//cout<<root_node[i]->element<<endl;
		construct_for(root_node[i]);
		//cout<<"???"<<endl;
		//from_bt.out_test(from_bt.treeroot[i]);
	} 
		
}

template<class T>
void btree<T>::construct_for(BTNode<T> * rtmp)
{
	if(rtmp==NULL)return;
	BTNode<T> *x=rtmp->leftchild;
	from_bt.fore[rtmp->element].element=rtmp->element;
	if(x!=NULL)
	{
		//cout<<"x此时:"<<x->element<<endl;
		from_bt.fore[rtmp->element].children.push_back(x->element);
		from_bt.fore[x->element].parent=rtmp->element;		
		from_bt.fore[x->element].element=x->element;		
		BTNode<T> *r=x->rightchild;
		while(r!=NULL)
		{
			//cout<<"r此时:"<<r->element<<endl;
			from_bt.fore[rtmp->element].element=rtmp->element;
			from_bt.fore[rtmp->element].children.push_back(r->element);
			from_bt.fore[r->element].element=r->element;
			from_bt.fore[r->element].parent=rtmp->element;
			r=r->rightchild;
		}
	}
	construct_for(x);
	construct_for(rtmp->rightchild);
}


template<class T>
void BT<T>::preorder(BTNode<T>* t)
{
	if (t != NULL)
	{
		visit(t);
		preorder(t->leftchild);
		preorder(t->rightchild);
	}
}

template<class T>
void BT<T>::out_xor(BTNode<T>* t)
{
	if (t != NULL)
	{
		ans^=(t->element);
		out_xor(t->leftchild);
		out_xor(t->rightchild);
	}
}

template<class T>
void BT<T>::inorder(BTNode<T>* t)
{	if (t != NULL)
	{
		inorder(t->leftchild);
		BT<T>::visit(t);
		inorder(t->rightchild);
	}
}

template<class T>
void BT<T>::postorder(BTNode<T>* t)
{
	if (t != NULL)
	{
		postorder(t->leftchild);
		postorder(t->rightchild);
		BT<T>::visit(t);
	}
}

template<class T>
void BT<T>::levelorder(BTNode<T>* t)
{
	list<BTNode<T>* > q;
	while (t != NULL)
	{
		BT<T>::visit(t);
		if (t->leftchild != NULL)
			q.push_back(t->leftchild);
		if (t->rightchild != NULL)
			q.push_back(t->rightchild);

		if (!q.empty())
			t = q.front();
		else return;
		q.pop_front();
	}
}

template<class T>
BTNode<T>* BT<T>::find(int node,BTNode<T>* t)
{
	list<BTNode<T>* > q;
	while (t != NULL)
	{
		if(t->element==node)
		return t;
		if (t->leftchild != NULL)
			q.push_back(t->leftchild);
		if (t->rightchild != NULL)
			q.push_back(t->rightchild);

		if (!q.empty())
			t = q.front();
		else return NULL;
		q.pop_front();
	}
}

template<class T>
void BT<T>::initial(int num)
{
	treesize = num;
	trans=0;
	int node_root;
	cin>>node_root;
	BTNode<T> **temp = new BTNode<T>*[treesize+1];
	for (int i = 1; i <= treesize; ++i)
		temp[i] = new BTNode<T>(i);
	root = temp[node_root];

	int A, left, right;
	for (int j = 1; j <= treesize; ++j)
	{
		cin >> A>> left >> right;
		if (left != -1)
			temp[j]->leftchild = temp[left];
		else temp[j]->leftchild = NULL;
		if (right != -1)
			temp[j]->rightchild = temp[right];
		else temp[j]->rightchild = NULL;
	}
	delete[]temp;
}

template<class T>
void BT<T>::fun5()
{
	int pos,father,node;
	cin>>pos>>father>>node;
	BTNode<T>* f=find(father,root);
	BTNode<T>* _node=new BTNode<T>(node);
	if(pos==0)
		f->leftchild=_node;
	else f->rightchild=_node;
		treesize++;
}

template<class T>
void BT<T>::fun6()
{
	if(trans==0)
	{
		ans=0;
		out_xor(root);
		cout<<ans<<endl;
	}
}



/*---------------------------------------------------------------------------*/
template<class T>
void forest<T>::initial(int num1,int num2)
{
	cout<<"请输入森林中各棵树初始的根节点:"<<endl;
	trans=0;
	treenum=num1;
	forestsize=num2;
	int rootx;
	for(int i=0;i<treenum;++i)
	{
		cin>>rootx;
		treeroot[i]=rootx;	
		fore[rootx].element=rootx;
		fore[rootx].parent=-1;	
	}
	int A,B,nodex;
	for(int i=0;i<forestsize;++i)
	{
		cin>>A>>B;
		for(int k=0;k<B;++k)
		{
			cin>>nodex;
			fore[nodex].element=nodex;
			fore[A].children.push_back(nodex);
			fore[nodex].parent=A;
		}
	}
	cout<<"森林已经初始化完毕!"<<endl<<endl; 
}

template<class T>
void forest<T>::fun1()
{
	int father,node;
		forestsize++;
		cin>>father>>node;
		if(father==-1)
		{
			fore[node].element=node;
			fore[node].parent=-1;
			treeroot[treenum++]=node;
		}
		else
		{
			fore[father].children.push_back(node);
			fore[node].element=node;
			fore[node].parent=father;
		}
}

template<class T>
void forest<T>::fun2()
{
	forestsize--;
	int father,node;
			cin>>father>>node;
			if(father==-1)
			{
				//删除根节点
				 for(int i=0;i<fore[node].children.size();++i)
				 {
				 	int curnode=fore[node].children[i];
				 	fore[curnode].parent=-1;
				 	treeroot[treenum++]=curnode;		 	
				 }
				 //将根节点从treeroot数组中删除
				 int mark=0;
				 for( mark=0;mark<treenum;++mark)
				 	if(treeroot[mark]==node)break;
				treenum--;
				for(int i=mark;i<treenum;++i)
				treeroot[i]=treeroot[i+1];
				fore[node].children.clear(); 
			}
			else
			{
				for(int i=0;i<fore[node].children.size();++i)
				 {
				 	int curnode=fore[node].children[i];
				 	fore[curnode].parent=-1;
				 	treeroot[treenum++]=curnode;		 	
				 }
				 //将node从father的孩子中删除
				 vector<int>::iterator ia;
				 ia=find(fore[father].children.begin(),fore[father].children.end(),node);
				 fore[father].children.erase(ia);
			}
}
template<class T>
void forest<T>::fun3()
{
	int a,b;
	cin>>a>>b;
	fore[b].parent=a;
	fore[a].children.push_back(b);
	int i=0;
	for(i=0;i<treenum;++i)
		if(treeroot[i]==b)break;
	treenum--;
	for(int k=i;k<treenum;++k)
		treeroot[k]=treeroot[k+1];
}

template<class T>
void forest<T>::fun4()
{
		to_bt();
}

template<class T>
void forest<T>::fun6()
{
	//升序输出每棵树各元素的异或值
	if(trans==0)
	{
		sort(treeroot,treeroot+treenum);
		for(int i=0;i<treenum;++i)
		{
			ans=0;
			out_xor(treeroot[i]);
			cout<<ans<<" ";
		}
		cout<<endl;	
	}
	else
	{
		from_forest.ans=0;
		from_forest.out_xor(from_forest.root);
		cout<<from_forest.ans<<endl;
	}
}

template<class T>
void forest<T>::to_bt()
{
	trans=1;
	//将所有节点排序
	for(int i=1;i<=forestsize;++i)
		sort(fore[i].children.begin(),fore[i].children.end()); 
	for(int i=0;i<treenum;++i)
		{
			vector<int> v;//存放所有不止一个孩子的节点
			v.clear();
			list<int> l;
			l.clear();
			//层次遍历寻找所有孩子多于1个的节点
			l.push_back(treeroot[i]);		
			while(!l.empty())
			{
				int f=l.front();
				if(fore[f].children.size()>1)v.push_back(f);
				for(int g=0;g<fore[f].children.size();g++)
				l.push_back(fore[f].children[g]);
				l.pop_front();
			} 

			//从最后一个元素开始处理
			for(int j=v.size()-1;j>=0;--j)
			{
				for(int h=0;h<fore[v[j]].children.size()-1;++h)
				{
					int curbro=fore[v[j]].children[h];
					int curbro2=fore[v[j]].children[h+1];
					fore[curbro].children.push_back(curbro2);
					fore[curbro2].parent=curbro;
				}
				vector<int>::iterator ie=fore[v[j]].children.begin()+1;
				fore[v[j]].children.erase(ie,fore[v[j]].children.end());
				} 
		} 	
		sort(treeroot,treeroot+treenum);
			 BTNode<T>* allbt[treenum];
			 //遍历每一棵树进行构造
			 for(int i=0;i<treenum;++i)
			 {
			 	allbt[i]=new BTNode<T>(treeroot[i]);
			 	construct(allbt[i],treeroot[i]);
			 } 
			 //合并所有的二叉树
			 for(int i=0;i<treenum-1;++i)
			 allbt[i]->rightchild=allbt[i+1];
			 from_forest.root=allbt[0]; 	 			 			  
}

template<class T>
void forest<T>::construct(BTNode<T> *roottmp,int nodetmp)
{
	for(int i=0;i<fore[nodetmp].children.size();++i)
	{
		if(i==0)
		{
			roottmp->leftchild=new BTNode<T>(fore[nodetmp].children[0]);
			construct(roottmp->leftchild,fore[nodetmp].children[0]);
		}
		else if(i==1)
		{
			roottmp->rightchild=new BTNode<T>(fore[nodetmp].children[1]);
			construct(roottmp->rightchild,fore[nodetmp].children[1]);
		}
	}
}
template<class T>
void forest<T>::out_xor(int rootnode)
{
	ans^=rootnode;
	for(int i=0;i<fore[rootnode].children.size();++i)
		out_xor(fore[rootnode].children[i]);
}

template<class T>
void forest<T>::out_test(int rootnode)
{
	cout<<rootnode<<" ";
	for(int i=0;i<fore[rootnode].children.size();++i)
		out_test(fore[rootnode].children[i]);
}

int main()
{
	cout<<"请选择初始化ADT的类型(输入0表示初始化森林,输入1表示初始化二叉树):"<<endl;
	int K,M,N,Q,flag;
	cin>>K;
	if(K==1)
	{
		cout<<"您已经选择初始化二叉树,请输入1表示一棵树:"<<endl;
		cin>>M;
		cout<<"请输入初始化二叉树中节点的数目:"<<endl;
		cin>>N; 
		btree<int> x;
		x.initial(N);
		cout<<"接下来您可以对二叉树/森立进行操作,各操作表示如下:"<<endl;
		cout<<"1 father node"<<"--------表示为森林中树的结点 father "
		<<"插入一个孩子结点 node "<<endl;
		cout<<"2 father node"<<"--------表示删除森林中的结点 node , "
		<<"其中 father 是 node 的父亲结点"<<endl;
		cout<<"3 a      b   "<<"--------表示在森林中的根结点 a, b 间插入一条边, "
		<<"其中 a 为 b 结点的父亲。"<<endl;
		cout<<"4 "<<"-------------------将该森林转换为二叉树"<<endl;
		cout<<"5 pos father node "<<"---表示为二叉树的 father 结点插入一个孩子 node"<<endl;
		cout<<"6 "<<"-------------------显示森林/二叉树。"<<endl<<endl;
		cout<<"您需要输入操作的数量:"<<endl; 	
		int Q;
		cin >> Q;
		for(int i=0;i<Q;++i)
		{
			cout<<"请输入操作:"; 
			cin>>flag;
			switch(flag)
			{
				case 1:cout<<"------>------>操作1成功!"; x.fun1();cout<<endl<<endl;break;
				case 2:cout<<"------>------>操作2成功!"; x.fun2();cout<<endl<<endl;break;
				case 3:cout<<"------>------>操作3成功!"; x.fun3();cout<<endl<<endl;break;
				case 4:cout<<"------>------>操作4成功!"; x.fun4();cout<<endl<<endl;break;
				case 5:cout<<"------>------>操作5成功!"; x.fun5();cout<<endl<<endl;break;
				case 6:cout<<"------>------>操作6成功!"; x.fun6();cout<<endl<<endl;break;				
			}
		}
	}
	else
	{
		cout<<"您已经选择初始化森林,请输入森林中树的数目:"<<endl;
		cin>>M;
		cout<<"您已经选择初始化"<<M<<"棵树,请输入初始化节点的数目:"<<endl;
		cin>>N; 
		forest<int> y;
		y.initial(M,N);
		cout<<"接下来您可以对二叉树/森林进行操作,各操作表示如下:"<<endl;
		cout<<"1 father node"<<"--------表示为森林中树的结点 father "
		<<"插入一个孩子结点 node "<<endl;
		cout<<"2 father node"<<"--------表示删除森林中的结点 node , "
		<<"其中 father 是 node 的父亲结点"<<endl;
		cout<<"3 a      b   "<<"--------表示在森林中的根结点 a, b 间插入一条边, "
		<<"其中 a 为 b 结点的父亲。"<<endl;
		cout<<"4 "<<"-------------------将该森林转换为二叉树"<<endl;
		cout<<"5 pos father node "<<"---表示为二叉树的 father 结点插入一个孩子 node"<<endl;
		cout<<"6 "<<"-------------------显示森林/二叉树。"<<endl<<endl;
		cout<<"您需要输入操作的数量:"<<endl; 
		cin>>Q;
		for(int i=0;i<Q;++i)
		{
			cout<<"请输入操作:"; 
			cin>>flag;
			switch(flag)
			{
				case 1:	cout<<"------>------>操作1成功!";y.fun1();cout<<endl<<endl;break;
				case 2: cout<<"------>------>操作2成功!";y.fun2();cout<<endl<<endl;break;
				case 3: cout<<"------>------>操作3成功!";y.fun3();cout<<endl<<endl;break;
				case 4: cout<<"------>------>操作4成功!";y.fun4();cout<<endl<<endl;break;
				case 5: cout<<"------>------>操作5成功!";y.fun5();cout<<endl<<endl;break;
				case 6: cout<<"------>------>操作6成功!"
				<<"显示如下:";y.fun6();cout<<endl;break;				
			}
		}
	}

	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值