森林和二叉树的转换 (孩子兄弟表示法+数组模拟

#include 
#include
#include
#pragma warning(disable:4996)
//#define father 3
using namespace std;
int k, m, n;
int Q, op; int flag;
int trees[5105][3];
int btree[5105][3];
int* troot; int btroot;
bool cmp(int a,int b) {
     
	return a < b;
}
int re=0;
void test0(int root) {
     
	if (root == -1) {
     
		return ;
	}
	// << root <<" ";
	re = re ^ root;
	test0(trees[root][1]);
	test0(trees[root][2]);
}
void test1(int root) {
     
	if (root == -1) {
     
		return;
	}
	// << root <<" ";
	re = re ^ root;
	test1(btree[root][1]);
	test1(btree[root][2]);
}
void pre() {
     
  for(int i=0;i<5105;i++)
	  for (int j = 0; j < 3; j++)
	  {
     
		  trees[i][j] = -1; btree[i][j] = -1;
	  }
}
void deleteroot(int node) {
     
	int mark = 0;
	for (int j = 0; j < m; j++)if (troot[j] == node)mark = j;//troot = troot + 1;
	while (mark < m - 1) {
     
		troot[mark] = troot[mark + 1]; mark++;
	}troot[mark] = -1;
	m--;
}
void testout() {
     
	for (int j = 0; j < m; j++)cout << "根:" << troot[j] << " ";
	cout << endl;
	for (int j = 0; j < m; j++)
	{
     
		test0(troot[j]); cout << endl;
	}
}
void clone(int kind) {
     
	if (kind == 1) {
     //将二叉树数组复制为森林
		for (int i = 0; i < 5105; i++)
			for (int j = 0; j < 3; j++)
				trees[i][j] = btree[i][j];
	}
	if (kind == 0) {
     //森林复制为二叉树
		for (int i = 0; i < 5105; i++)
			for (int j = 0; j < 3; j++)
				btree[i][j]= trees[i][j];
	}
}
void trans(int flag) {
     
if (flag == 0) {
     //森林转二叉树
	sort(troot, troot + m, cmp);
	int p = troot[0];
	for (int i = 1; i < m; i++) {
     
		trees[p][2] = troot[i];
		p = troot[i];
	}
	for (int j = 1; j < m; j++)troot[j] = -1;
	m = 1; btroot = troot[0];
	//testout();
	clone(0);

}
else if (flag == 1) {
     //二叉树转森林
	int p = btroot; int pp =p;
	//test1(btroot);
	while (p != -1) {
     
		pp = p;
		troot[m - 1] = pp;
		p = btree[p][2];
		btree[pp][2] = -1;
		m++;
	}
	m--;
	clone(1);
	sort(troot, troot + m, cmp);
	//testout();

}

}
void insertbt() {
     
	int ops, fa, node;
	cin >> ops >> fa >> node;
	if (ops == 0) {
     
		btree[fa][2] = node;
	}
	if (ops == 1) {
     
		btree[fa][1] = node;
	}
}
void meun() {
     
	pre();
	cin >> k >> m >> n;
	troot = new int[m+1000]; for (int i = 0; i <m+1000; i++)troot[i] = -1;
	//cout << trees[11][1] << "  vdfv  " << trees[11][2] << endl;
	if (k == 0) {
     
		flag = 0;
		for (int i = 0; i < m; i++)cin >> troot[i]; 
		for (int i = 0; i < n; i++) {
     
			int a, b, * nodes;
			cin >> a >> b;  nodes = new int[b + 1]; for (int j = 0; j < b; j++)nodes[j] = -1; nodes[b] = -1;
			for (int j = 0; j < b; j++)cin >> nodes[j];
			sort(nodes, nodes + b, cmp);
			if (b != 0) {
     
				trees[a][0] = 0;
				trees[a][1] = nodes[0];
				int p = 1; int j = nodes[0];
				while (nodes[p] != -1) {
     
					trees[j][0]=0;
					trees[j][2] = nodes[p];
					j = nodes[p];     p++;
				}
			}
			else {
     
				trees[a][0] = 0;
			}
		}
	}
	if (k == 1) {
     
		flag = 1;
		cin >> btroot;
		for (int i = 0; i < n; i++) {
     
			int a, l, r;
			cin >> a >> l >> r;
			btree[a][1] = l; if (l != -1)btree[l][0] = a;
			btree[a][2] = r; if (r != -1)btree[r][0] = a;
		}
	}


	cin >> Q;
	for (int i = 0; i < Q; i++) {
     
		cin >> op;
		switch (op) {
     
		case 1:
		{
     
			int fa, node;
			cin >> fa >> node;
			if (fa == -1) {
       trees[node][0] = 0; troot[m] = node; m++; }//插入根节点
			else//非根节点
			{
     
				trees[node][0] = 0;
				int p = trees[fa][1];
				if (node <= p || p == -1) {
     //若小于等于孩子节点||没孩子 则成为该fa的孩子
					int ppp = trees[fa][1];
					trees[fa][1] = node;
					trees[node][2] = ppp;
				}
				else {
     
					int pp=0;
					while (node > p&& p != -1) {
     
						pp = p;
						p = trees[p][2];
					}
					trees[pp][2] = node;
					trees[node][2] = p;
				}
			}
			sort(troot, troot + m, cmp);
			break;
		}
		case 2:
		{
     
			int fa, node; cin >> fa >> node;
			if (fa == -1) {
     //删掉根节点  则其子节点都会成为新树
				deleteroot(node);
				if (trees[node][1] != -1) {
     //删掉的根有孩子
					int p = 0;
					p = trees[node][1]; int pp;
					while (p != -1) {
     
					    troot[m] = p;
						pp = p;
						p = trees[p][2];
						trees[pp][2] = -1;
						m++;
					}
					trees[node][0] = -1; trees[node][1] = -1; trees[node][2] = -1;
					sort(troot, troot + m, cmp);
				}
				else {
     //没孩子
					trees[node][0] = -1; trees[node][1] = -1; trees[node][2] = -1;
				}
			}
			else if (fa != -1) {
     //待删除的点不是根节点 其所有孩子都成为新的树
				if (node == trees[fa][1]) {
       //分情况 1待删除点是其父节点第一个孩子 2其他孩子//我叫白小飞 我遭遇了无法想象的bug,我要活下去,并且干掉更多的bug。awsl
					int p = node; trees[fa][1] = trees[p][2];//父节点孩子改变为待删除节点兄弟;
					if (trees[p][1]!=-1) {
     //待删除节点有孩子
						int pp = 0; pp = trees[p][1]; int ppp;
						while (pp != -1) {
     
							troot[m] = pp;
							ppp = pp; 
							pp = trees[pp][2];
							trees[ppp][2] = -1;
							m++;
						}
						sort(troot, troot + m, cmp);
						trees[p][0] = -1; trees[p][1] = -1; trees[p][2] = -1;
					}
					else if(trees[p][1]==-1) {
     //待删除节点无孩子  删除该节点
						trees[p][0] = -1; trees[p][1] = -1; trees[p][2] = -1;
					}
				}
				else {
                             //分情况 2其他孩子
					int p = trees[fa][1]; int pp=0;
					while (p!=-1&&p != node) {
     
						pp = p; p = trees[p][2];
					}
					trees[pp][2] = trees[p][2];//p此时为待删除节点
					if (trees[p][1] != -1) {
     //待删除节点有孩子
						int pp = 0;pp= trees[p][1]; int ppp;
						while (pp != -1) {
     
							troot[m] = pp;
							ppp = pp;
							pp = trees[pp][2];
							trees[ppp][2] = -1;
							m++;
						}
						sort(troot, troot + m, cmp);
						trees[p][0] = -1; trees[p][1] = -1; trees[p][2] = -1;
					}
					else if (trees[p][1] == -1) {
     //待删除节点无孩子  删除该节点
						trees[p][0] = -1; trees[p][1] = -1; trees[p][2] = -1;
					}
					
				}
			}
			break;
		}
		case 3:
		{
     
			int a, b; cin >> a >> b;
			deleteroot(b);
			int p = trees[a][1]; int pp=0;
			if (p == -1)trees[a][1] = b;
			else {
     
				while (p < b && p != -1) {
     
					pp = p;
					p = trees[p][2];
				}
				if (p == trees[a][1]) {
     
					trees[a][1] = b;
					trees[b][2] = p;
				}
				else {
     
					trees[pp][2] = b;
					trees[b][2] = p;
				}

			}
			break;
		}
		case 4:
		{
     
			trans(flag);
			flag = (flag + 1) % 2;
			//testout();
			break;
		}
		case 5:
		{
     
			insertbt();
			break;
		}
		case 6:
		{
     
			if (flag == 0) {
     
				sort(troot, troot + m, cmp);
				for (int j = 0; j < m; j++)
				{
     
					re = 0;
					test0(troot[j]);
					cout << re << " ";
				}
				cout << endl;
			}
			else if (flag == 1) {
     
				re = 0;
				test1(btroot);
				cout << re << endl;
			}
			break;
		}


		}
	}

}




int main()
{
     

	//freopen("input13.txt", "r", stdin); 
	//freopen("output13.txt", "w", stdout); 
	meun();
	//fclose(stdin);
//fclose(stdout);
	return 0;
}

你可能感兴趣的:(二叉树,c++,数据结构)