输入格式说明:略
#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;
}