Encode N-ary Tree to Binary Tree
There are a lot of solutions to convert a N-ary tree to a binary tree. We only introduce one classical solution.
The strategy follows two rules:
- The
left child
of each node in the binary tree isthe next sibling
of the node in the N-ary tree. - The
right child
of each node in the binary tree isthe first child
of the node in the N-ary tree.
Here is an example to help you understand this strategy:
Using this strategy, you can simply convert a N-ary tree to a binary tree recursively. Also, you can easily recover the N-ary tree from the binary tree you converted. The recursion recovery strategy for each node is:
- Deal with its children recursively.
- Add its
left child
asthe next child of its parent
if it has a left child. - Add its
right child
asthe first child of the node itself
if it has a right child.
Here is an example to help you understand this strategy:
Leetcode Serialize

{"$id":"1","children":[{"$id":"2","children":[{"$id":"5","children":[],"val":5},
{"$id":"6","children":[],"val":6}],"val":3},{"$id":"3","children":[],"val":2},
{"$id":"4","children":[],"val":4}],"val":1}
Final Version
class Codec {
public:
// Encodes an n-ary tree to a binary tree.
TreeNode* encode(Node* root) {
if (root == nullptr) return nullptr;
TreeNode* brt = new TreeNode(root->val);
brt->left = nullptr;
if (root->children.size() == 0) {
brt->right = nullptr;
return brt;
} else {
brt->right = encode(root->children[0], root, 0);
return brt;
}
}
// Decodes your binary tree to an n-ary tree.
Node* decode(TreeNode* root) {
if (root == nullptr) return nullptr;
cout << endl;
preBTree(root);
vector<Node*> children;
Node* nrt = new Node(root->val, children);
decode(root->right, nrt);
return nrt;
}
private:
TreeNode* encode(Node* root, Node* parent, int index) {
if (root == nullptr) return nullptr;
TreeNode* brt = new TreeNode(root->val);
if (index + 1 < parent->children.size()) {
brt->left = encode(parent->children[index+1], parent, index+1);
} else {
brt->left = nullptr;
}
if (root->children.size() > 0) {
brt->right = encode(root->children[0], root, 0);
}
return brt;
}
void decode(TreeNode* root, Node* parent) {
if (!root) return;
vector<Node*> children;
Node* nrt = new Node(root->val, children);
decode(root->right, nrt);
parent->children.push_back(nrt);
if(root->left) decode(root->left, parent);
}
void preNTree(Node* root) {
if (!root) return;
cout << root->val << ' ';
for (auto it : root->children) {
preNTree(it);
}
}
void preBTree(TreeNode* root) {
if (!root) return;
cout << root->val << ' ';
preBTree(root->left);
preBTree(root->right);
}
};
N-ary Tree to Binary Tree First version
/*
// Definition for a Node.
class Node {
public:
int val = NULL;
vector<Node*> children;
Node() {}
Node(int _val, vector<Node*> _children) {
val = _val;
children = _children;
}
};
*/
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Codec {
public:
// Encodes an n-ary tree to a binary tree.
TreeNode* encode(Node* root) {
if (root == nullptr) return nullptr;
// preNTree(root);
// convert root node first
TreeNode* brt = new TreeNode(root->val);
brt->left = nullptr;
if (root->children.size() == 0) {
brt->right = nullptr;
return brt;
//} else {
// brt->right = encode(parent->children[0], root, 0);
// return brt;
//}
} else if (root->children.size() == 1) {
brt->right = new TreeNode(root->children[0]->val);
return brt;
} else if (root->children.size() >= 2) {
brt->right = encode(root->children[0], root, 0);
return brt;
}
}
// Decodes your binary tree to an n-ary tree.
Node* decode(TreeNode* root) {
cout << endl;
preBTree(root);
return nullptr;
}
private:
TreeNode* encode(Node* root, Node* parent, int index) {
if (root == nullptr) return nullptr;
TreeNode* brt = new TreeNode(root->val);
// cout << root->val << endl;
cout << root->val << ": " << parent->children.size() << endl;
if (index + 1 < parent->children.size()) {
// bug: brt->left = encode(parent->children[index+1], root, index+1);
brt->left = encode(parent->children[index+1], parent, index+1);
} else {
brt->left = nullptr;
}
if (root->children.size() > 0) {
brt->right = encode(root->children[0], root, 0);
}
return brt;
}
void preNTree(Node* root) {
if (!root) return;
cout << root->val << ' ';
for (auto it : root->children) {
preNTree(it);
}
}
void preBTree(TreeNode* root) {
if (!root) return;
cout << root->val << ' ';
preBTree(root->left);
preBTree(root->right);
}
};
// Your Codec object will be instantiated and called as such:
// Codec codec;
// codec.decode(codec.encode(root));
Bug corner case:
class Codec {
public:
// Encodes an n-ary tree to a binary tree.
TreeNode* encode(Node* root) {
if (root == nullptr) return nullptr;
// preNTree(root);
// convert root node first
TreeNode* brt = new TreeNode(root->val);
brt->left = nullptr;
if (root->children.size() == 0) {
brt->right = nullptr;
return brt;
} else {
brt->right = encode(root->children[0], root, 0);
return brt;
}
// bug: when first root children size == 1, will never call encode()
//} else if (root->children.size() == 1) {
// brt->right = new TreeNode(root->children[0]->val);
// return brt;
//} else if (root->children.size() >= 2) {
// brt->right = encode(root->children[0], root, 0);
// return brt;
//}
}
// Decodes your binary tree to an n-ary tree.
Node* decode(TreeNode* root) {
if (root == nullptr) return nullptr;
cout << endl;
preBTree(root);
vector<Node*> children;
Node* nrt = new Node(root->val, children);
decode(root->right, nrt);
return nrt;
}
private:
TreeNode* encode(Node* root, Node* parent, int index) {
if (root == nullptr) return nullptr;
TreeNode* brt = new TreeNode(root->val);
if (index + 1 < parent->children.size()) {
brt->left = encode(parent->children[index+1], parent, index+1);
} else if (index + 1 == parent->children.size()) {
brt->left = nullptr;
} else {
brt->left = nullptr;
}
if (root->children.size() > 0) {
brt->right = encode(root->children[0], root, 0);
}
return brt;
}
void decode(TreeNode* root, Node* parent) {
// bug: forgot return
//if (!root) parent->children = parent->children.push_back(nullptr);
if (!root){
// bug: push extra nullptr to vector, instead of empty vector as example
//parent->children.push_back(nullptr);
return;
}
vector<Node*> children;
Node* nrt = new Node(root->val, children);
decode(root->right, nrt);
parent->children.push_back(nrt);
if(root->left) decode(root->left, parent);
}
void preNTree(Node* root) {
if (!root) return;
cout << root->val << ' ';
for (auto it : root->children) {
preNTree(it);
}
}
void preBTree(TreeNode* root) {
if (!root) return;
cout << root->val << ' ';
preBTree(root->left);
preBTree(root->right);
}
};