森林与二叉树的转换实现

输入格式说明:略

#include<iostream>
#include<queue>
using namespace std;


//类的声明
class Forest;
class BinaryTree;

//森林
struct Node {
	int val;
	Node *next;

	Node() { 
		val = -1;
		next = NULL;
	}
	Node(int v) :val(v) { next = NULL; }
};
struct Root {
	int val;
	int index;
	Root *next;

	Root() { 
		val = -1;
		index = -1;
		next = NULL; 
	}
	Root(int i,int v,Root *n)
		:val(v),index(i),next(n){}
};
//二叉树
struct initNode {
	int A;
	int l;
	int r;
	initNode() {
		A = 0;
		l = 0;
		r = 0;
	}
	initNode(int a, int L, int R)
		:A(a), l(L), r(R)
	{}
};
struct binaryTreeNode {
	int element;
	binaryTreeNode *leftChild, *rightChild;

	binaryTreeNode() {
		element = -1;
		leftChild = NULL;
		rightChild = NULL;
	}
	binaryTreeNode(int ele) {
		element = ele;
		leftChild = NULL;
		rightChild = NULL;
	}
};

class Forest {
private:
	Node **elements;
	int nodeSize; //节点的数目
	int arrayLength; //当前数组已放置多长
	int arraySize; //当前数组大小
	Root *roots; //记录各根节点的位置链表,按值大小有序放置
	int treeSize; //森林共有多少棵树
	int treeLength; //森林已记录多少树根

public:
	Forest(){}
	Forest(const Forest &c) {
		arrayLength = c.arrayLength;
		arraySize = c.arraySize;
		roots = c.roots;
		elements = new Node*[arraySize];
		for (int i = 0; i < arraySize; i++) {
			elements[i] = c.elements[i];
		}
	}
	//私有变量的初始化
	void init_val(int treeNum, int nodeNum) {
		arraySize = 5000;
		elements = new Node *[arraySize];
		for (int i = 0; i < arraySize; i++) {
			elements[i] = new Node;
		}
		arrayLength = 0;
		nodeSize = nodeNum;

		roots = NULL;
		treeSize = treeNum;
		treeLength = 0;
	}
	void display2(); //for test: display the forest structure

	int findInNodes(int val); //查找元素的下标
	int findInRoots(int val); //查找根所在的下标位置
	void insertRoot(int index, int val);
	int insertNode(int val); //返回插入的下标
	void insertChild_Index(int index, int val); //孩子链表中有序插入元素
	int eraseInRoots(int val);
	//对外的操作
	void initializeRoot(int r);
	void initialize(int rootVal, int childNum, int *val);
	void insertChild(int father, int node);
	void eraseNode(int father, int node);
	void insertRootEdge(int father, int node);
	void display();
	binaryTreeNode* toBinaryTree();
};
int Forest::findInNodes(int val) {
	for (int i = 0; i < arrayLength; i++)
		if (elements[i] != NULL && elements[i]->val == val)
			return i;
	return -1;
}
int Forest::findInRoots(int val) {
	Root *temp = roots;
	while (temp != NULL) {
		if (temp->val == val)
			return temp->index;
		temp = temp->next;
	}
	return -1;
}
void Forest::insertRoot(int index, int val) {
	Root *insertElement = new Root(index, val, NULL);
	Root *temp = roots;
	if (temp == NULL || temp->val > val) {
		insertElement->next = temp;
		roots = insertElement;
	}
	else {
		while (temp->next != NULL && temp->next->val < val)
			temp = temp->next;
		if (temp->next == NULL)
			temp->next = insertElement;
		else if (temp->next != NULL && temp->next->val != val) {
			insertElement->next = temp->next;
			temp->next = insertElement;
		}
	}
}
int Forest::insertNode(int val) {
	if (arrayLength == arraySize) {
		arraySize *= 2;
		Node **newElements;
		newElements = new Node*[arraySize];
		for (int i = 0; i < arraySize; i++)
			newElements[i] = new Node;
		for (int i = 0; i < arrayLength; i++)
			newElements[i] = elements[i];
		elements = newElements;
	}
	elements[arrayLength]->val = val;
	elements[arrayLength]->next = NULL;
	return arrayLength++;
}
void Forest::insertChild_Index(int index, int val) {
	Node *insertElement = new Node(val);
	Node *temp = elements[index];
	if (temp->next == NULL || temp->next->val > val) {
		insertElement->next = temp->next;
		temp->next = insertElement;
	}
	else {
		Node *temp2 = temp->next;
		while (temp2->next != NULL && temp2->next->val < val)
			temp2 = temp2->next;
		if (temp2->next == NULL)
			temp2->next = insertElement;
		else if (temp2->next != NULL && temp2->next->val != val)
		{
			insertElement->next = temp2->next;
			temp2->next = insertElement;
		}
	}
}
int Forest::eraseInRoots(int val) {
	Root *temp = roots;
	int index = -1;
	if (temp->val == val) {
		index = temp->index;
		roots = temp->next;
	}
	else {
		while (temp->next != NULL && temp->next->val != val)
			temp = temp->next;
		if (temp->next != NULL) {
			index = temp->next->index;
			temp->next = temp->next->next;
		}
	}
	return index;
}
//对外操作
void Forest::initializeRoot(int r) {
	int index = insertNode(r);
	insertRoot(index, r);
	++treeLength;
}
void Forest::initialize(int root, int childNum, int *val) {
	int index = findInNodes(root);
	if (index == -1)
		index = insertNode(root);

	for (int i = 0; i < childNum; i++)
		insertChild_Index(index, val[i]);
}
void Forest::insertChild(int father, int node) {
	int index = findInNodes(node);
	if (index == -1)
		index = insertNode(node);
	if (father == -1)
		insertRoot(index, node);
	else {
		int rootIndex = findInNodes(father);
		insertChild_Index(rootIndex, node);
	}
}
void Forest::eraseNode(int father, int node) {
	int rootIndex;
	if (father == -1)
		rootIndex = eraseInRoots(node);
	else if (father != -1) {
		int indexTemp = findInNodes(father);

		Node *temp = elements[indexTemp];
		while (temp->next != NULL && temp->next->val != node)
			temp = temp->next;
		if (temp != NULL)
			temp->next = temp->next->next;
		rootIndex = findInNodes(node);
	}

	Node *children = elements[rootIndex]->next;
	elements[rootIndex] = NULL;
	while (children != NULL) {
		int index = findInNodes(children->val);
		insertRoot(index, children->val);
		children = children->next;
	}
}
void Forest::insertRootEdge(int father, int node) {
	eraseInRoots(node);
	int index = findInRoots(father);
	insertChild_Index(index, node);
}
void Forest::display() {
	Root *tempR = roots;
	while (tempR != NULL) {
		queue<Node*> q;
		int index = tempR->index;
		int XOR = elements[index]->val;
		if (elements[index]->next != NULL)
			q.push(elements[index]->next);

		while (!q.empty()) {
			Node *temp = q.front();
			q.pop();
			XOR ^= temp->val;
			int childIndex = findInNodes(temp->val);
			if (temp->next != NULL)
				q.push(temp->next);
			if (elements[childIndex]->next != NULL)
				q.push(elements[childIndex]->next);
		}

		cout << XOR << " ";
		tempR = tempR->next;
	}
	cout << endl;
}
//for test
void Forest::display2() {
	cout << "Roots: index,val " << endl;
	Root *temp1 = roots;
	while (temp1 != NULL) {
		cout << temp1->index << "," << temp1->val << "  ";
		temp1 = temp1->next;
	}
	cout << endl;

	cout << "elements: val +children " << endl;
	for (int i = 0; i < arrayLength; i++) {
		if (elements[i] == NULL)
			continue;
		cout << elements[i]->val << ": ";
		Node *temp2 = elements[i]->next;
		while (temp2 != NULL) {
			cout << temp2->val << "  ";
			temp2 = temp2->next;
		}
		cout << endl;
	}
	cout << "		test over";
}
//构造二叉树搜索
binaryTreeNode* search(binaryTreeNode* root, int val) {
	queue<binaryTreeNode*> q;
	q.push(root);
	while (!q.empty()) {
		binaryTreeNode *temp = q.front();
		q.pop();
		if (temp->element == val)
			return temp;

		if (temp->leftChild != NULL)
			q.push(temp->leftChild);
		if (temp->rightChild != NULL)
			q.push(temp->rightChild);
	}
	return NULL;
}
binaryTreeNode* Forest::toBinaryTree() {
	binaryTreeNode *binaryTreeRoot = new binaryTreeNode(roots->val); //将要返回的二叉树根
	//先处理根节点
	binaryTreeNode *rootTemp = binaryTreeRoot;
	Root *temp = roots->next;
	while (temp != NULL) {
		rootTemp->rightChild = new binaryTreeNode(temp->val);
		rootTemp = rootTemp->rightChild;
		temp = temp->next;
	}

	//处理孩子链表的元素,q是各链的右孩子(兄弟链表)
	queue<binaryTreeNode*> q;
	for (int i = 0; i < arrayLength; i++) {
		if (elements[i] != NULL) {
			//制造一个节点,将在childrenRoot的左孩子链
			binaryTreeNode *childrenRoot = new binaryTreeNode(elements[i]->val);
			//处理孩子们
			Node *childrenTemp = elements[i]->next; //依次处理每一个孩子
			//ttt是要链在左孩子链上的头;childrenRootTemp是顺着这个链向右孩子链兄弟
			binaryTreeNode *childrenRootTemp = NULL, *ttt = NULL;
			while (childrenTemp != NULL) {
				binaryTreeNode *temp2 = new binaryTreeNode(childrenTemp->val);
				if (ttt == NULL) {
					childrenRootTemp = temp2;
					ttt = childrenRootTemp;
				}
				else {
					childrenRootTemp->rightChild = temp2;
					childrenRootTemp = childrenRootTemp->rightChild;
				}
				childrenTemp = childrenTemp->next;
			}
			childrenRoot->leftChild = ttt;
			q.push(childrenRoot);
		}
	}

	while (!q.empty()) {
		binaryTreeNode *temp3 = q.front();
		q.pop();
		binaryTreeNode *insertTemp = search(binaryTreeRoot, temp3->element);
		if (insertTemp != NULL) {
			insertTemp->leftChild = temp3->leftChild;
		}
		else
			q.push(temp3);
	}
	return binaryTreeRoot;
}


//二叉树
class BinaryTree {
private:
	binaryTreeNode *root;
	int size;

public:
	BinaryTree(){
		root = NULL;
		size = 0;
	}
	void init_val(int rootVal, int s) {
		root = new binaryTreeNode(rootVal);
		size = s;
	}
	void init_transFromForest(binaryTreeNode *r) {
		root = r;
	}

	binaryTreeNode* find(int val);

	void preOrder();
	void initialize(queue<initNode> q);
	void insert(int pos, int father, int node);
	Forest toForest();
};
binaryTreeNode* BinaryTree::find(int val) {
	queue<binaryTreeNode*> q;
	q.push(root);
	while (!q.empty()) {
		binaryTreeNode *temp = q.front();
		q.pop();
		if (temp->element == val)
			return temp;
		
		if (temp->leftChild != NULL)
			q.push(temp->leftChild);
		if (temp->rightChild != NULL)
			q.push(temp->rightChild);
	}
	return NULL;
}
void pre(binaryTreeNode *root, int *XOR) {
	if (root != NULL) {
		*XOR ^= root->element;
		pre(root->leftChild, XOR);
		pre(root->rightChild, XOR);
	}
}
void BinaryTree::preOrder() {
	int XOR = 0;
	pre(root,&XOR);
	cout << XOR << endl;
}
void BinaryTree::initialize(queue<initNode> q) {
	while (!q.empty()) {
		initNode node = q.front();
		q.pop();
		binaryTreeNode *temp = find(node.A);
		if (temp != NULL) {
			if (node.l != -1) {
				binaryTreeNode *leftTemp = new binaryTreeNode(node.l);
				temp->leftChild = leftTemp;
			}
			else if (node.l == -1)
				temp->leftChild = NULL;

			if (node.r != -1) {
				binaryTreeNode *rightTemp = new binaryTreeNode(node.r);
				temp->rightChild = rightTemp;
			}
			else if (node.r == -1)
				temp->rightChild = NULL;

			size++;
		}
		else if (temp == NULL)
			q.push(node);
	}
}
void BinaryTree::insert(int pos, int father, int node) {
	binaryTreeNode *temp = find(father);
	binaryTreeNode *child = new binaryTreeNode(node);
	if (pos == 0)
		temp->rightChild = child;
	else if (pos == 1)
		temp->leftChild = child;
	size++;
}

void form(binaryTreeNode *root, Forest &forest) {
	if (root != NULL) {
		//cout << root->element << " ";
		int index = forest.findInNodes(root->element);
		if (index == -1)
			index = forest.insertNode(root->element);
		//cout << index << "; ";
		binaryTreeNode *childTemp = root->leftChild;
		while (childTemp != NULL) {
			forest.insertChild_Index(index, childTemp->element);
			childTemp = childTemp->rightChild;
		}
		form(root->leftChild, forest);
		form(root->rightChild, forest);
	}
}
Forest BinaryTree::toForest() {
	Forest forest;
	forest.init_val(0, 0);

	//初始化森林的树根
	binaryTreeNode *tempOfRoot = root;
	while (tempOfRoot != NULL) {
		forest.initializeRoot(tempOfRoot->element);
		tempOfRoot = tempOfRoot->rightChild;
	}
	//cout << "======" << endl;
	form(root, forest);
	//cout << "======" << endl;
	//cout << ":::::::";
	//forest.display2();
	//cout << "::::::";
	return forest;
}



int main(void){
	Forest forest;
	BinaryTree binaryTree;

	int K, M, N;
	cin >> K >> M >> N;

	if (K == 0)
		forest.init_val(M, N);
	for (int i = 0; i < M; i++) {
		int temp;
		cin >> temp;
		if (K == 0)
			forest.initializeRoot(temp);
		else if (K == 1)
			binaryTree.init_val(temp, N);
	}

	queue<initNode> q;
	for (int i = 0; i < N; i++) {
		//初始化森林
		if (K == 0) {
			int A, B;
			cin >> A >> B;
			int *rootTemp = new int[B];
			for (int j = 0; j < B; j++)
				cin >> rootTemp[j];
			forest.initialize(A, B, rootTemp);
		}
		//初始化二叉树
		else if (K == 1) {
			int A, l, r;
			cin >> A >> l >> r;
			q.push(initNode(A, l, r));
		}
	}
	if (K == 1)
		binaryTree.initialize(q);

	int Q;
	cin >> Q;
	for (int i = 0; i < Q; i++) {
		int op;
		cin >> op;
		//森林插入节点
		if (op == 1) {
			int father, node;
			cin >> father >> node;
			forest.insertChild(father, node);
		}
		//森林删除节点
		else if (op == 2) {
			int father, node;
			cin >> father >> node;
			forest.eraseNode(father, node);
		}
		//在森林根节点插入边
		else if (op == 3) {
			int a, b;
			cin >> a >> b;
			forest.insertRootEdge(a, b);
		}
		//森林二叉树转换
		else if (op == 4) {
			if (K == 0) {
				binaryTreeNode *bn = forest.toBinaryTree();
				binaryTree.init_transFromForest(bn);
			}
			else if (K == 1) {
				forest = binaryTree.toForest();
			}
			K = 1 - K; //类型转换
		}
		//二叉树插入节点
		else if (op == 5) {
			int pos, father, node;
			cin >> pos >> father >> node;
			binaryTree.insert(pos, father, node);
		}
		//显示森林/二叉树
		else if (op == 6) {
			if (K == 0)
				forest.display();
			else if (K == 1)
				binaryTree.preOrder();
		}

	}

	system("pause");
	return 0;
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值