Succinct Encoding of Binary Tree
Last Updated :
23 Jul, 2025
A succinct encoding of Binary Tree takes close to the minimum possible space. The number of structurally different binary trees on n nodes is n'th Catalan number. For large n, this is about 4n; thus we need at least about log2 4n = 2n bits to encode it. A succinct binary tree therefore would occupy 2n + O(n) bits.
One simple representation that meets this bound is to visit the nodes of the tree in preorder, outputting "1" for a not-null node and "0" for a null node. If the tree contains data, we can simply simultaneously store it in a consecutive array in preorder.
Example:
Input:
Output: 1 1 0 0 1 0 1 0 0
Explanation: 1 indicates data and 0 indicates NULL.
Approach for encoding binary tree - O(n) Time and O(n) Space
The idea is to perform pre-order traversal of the binary tree. If the node is null, then append '0' to the string. Otherwise append '1' to the string and push the node value into a data array. Return the string and data array.
Below is the implementation of above approach:
C++
// C++ program to encode a
// binary tree.
#include <bits/stdc++.h>
using namespace std;
class Node {
public:
int data;
Node *left, *right;
Node (int x) {
data = x;
left = nullptr;
right = nullptr;
}
};
// Recursive pre-order function to
// encode a binary tree.
void encodeTreeRecur(Node* root, string &s,
vector<int> &arr) {
// For null nodes
if (root == nullptr) {
s.push_back('0');
return;
}
s.push_back('1');
// Store pre-order in array.
arr.push_back(root->data);
// Apply pre-order to left and
// right subtree.
encodeTreeRecur(root->left, s, arr);
encodeTreeRecur(root->right, s, arr);
}
pair<string, vector<int>> encodeTree(Node* root) {
string s = "";
vector<int> arr;
encodeTreeRecur(root, s, arr);
return make_pair(s, arr);
}
int main() {
// Binary tree
// 10
// / \
// 20 30
// / \ \
// 40 50 70
Node* root = new Node(10);
root->left = new Node(20);
root->right = new Node(30);
//root->left->left = new Node(40);
//root->left->right = new Node(50);
root->right->right = new Node(70);
pair<string, vector<int>> ans = encodeTree(root);
cout << ans.first << endl;
for (auto num: ans.second)
cout << num << " ";
cout << endl;
return 0;
}
Java
// Java program to encode a
// binary tree.
import java.util.ArrayList;
import java.util.List;
class Node {
int data;
Node left, right;
Node(int x) {
data = x;
left = null;
right = null;
}
}
class Pair {
String s;
ArrayList<Integer> arr;
Pair(String s1, ArrayList<Integer> arr1) {
s = s1;
arr = arr1;
}
}
class GfG {
// Recursive pre-order function to
// encode a binary tree.
static void encodeTreeRecur(Node root,
StringBuilder s, ArrayList<Integer> arr) {
// For null nodes
if (root == null) {
s.append('0');
return;
}
s.append('1');
// Store pre-order in array.
arr.add(root.data);
// Apply pre-order to left and
// right subtree.
encodeTreeRecur(root.left, s, arr);
encodeTreeRecur(root.right, s, arr);
}
static Pair encodeTree(Node root) {
StringBuilder s = new StringBuilder();
ArrayList<Integer> arr = new ArrayList<>();
encodeTreeRecur(root, s, arr);
return new Pair(s.toString(), arr);
}
public static void main(String[] args) {
// Binary tree
// 10
// / \
// 20 30
// / \ \
// 40 50 70
Node root = new Node(10);
root.left = new Node(20);
root.right = new Node(30);
root.left.left = new Node(40);
root.left.right = new Node(50);
root.right.right = new Node(70);
Pair ans = encodeTree(root);
System.out.println(ans.s);
for (int num : ans.arr)
System.out.print(num + " ");
System.out.println();
}
}
Python
# Python program to encode a
# binary tree.
class Node:
def __init__(self, x):
self.data = x
self.left = None
self.right = None
# Recursive pre-order function to
# encode a binary tree.
def encodeTreeRecur(root, s, arr):
# For null nodes
if root is None:
s.append('0')
return
s.append('1')
# Store pre-order in array.
arr.append(root.data)
# Apply pre-order to left and
# right subtree.
encodeTreeRecur(root.left, s, arr)
encodeTreeRecur(root.right, s, arr)
def encodeTree(root):
s = []
arr = []
encodeTreeRecur(root, s, arr)
return ''.join(s), arr
if __name__ == "__main__":
# Binary tree
# 10
# / \
# 20 30
# / \ \
# 40 50 70
root = Node(10)
root.left = Node(20)
root.right = Node(30)
root.left.left = Node(40)
root.left.right = Node(50)
root.right.right = Node(70)
ans = encodeTree(root)
print(ans[0])
for num in ans[1]:
print(num, end=" ")
print()
C#
// C# program to encode a
// binary tree.
using System;
using System.Collections.Generic;
class Node {
public int data;
public Node left, right;
public Node(int x) {
data = x;
left = null;
right = null;
}
}
class GfG {
// Recursive pre-order function to
// encode a binary tree.
static void encodeTreeRecur(Node root,
ref string s, List<int> arr) {
// For null nodes
if (root == null) {
s += '0';
return;
}
s += '1';
// Store pre-order in array.
arr.Add(root.data);
// Apply pre-order to left and
// right subtree.
encodeTreeRecur(root.left, ref s, arr);
encodeTreeRecur(root.right, ref s, arr);
}
static Tuple<string, List<int>> encodeTree(Node root) {
string s = "";
List<int> arr = new List<int>();
encodeTreeRecur(root, ref s, arr);
return new Tuple<string, List<int>>(s, arr);
}
static void Main(string[] args) {
// Binary tree
// 10
// / \
// 20 30
// / \ \
// 40 50 70
Node root = new Node(10);
root.left = new Node(20);
root.right = new Node(30);
root.left.left = new Node(40);
root.left.right = new Node(50);
root.right.right = new Node(70);
Tuple<string, List<int>> ans =
encodeTree(root);
Console.WriteLine(ans.Item1);
foreach (int num in ans.Item2)
Console.Write(num + " ");
Console.WriteLine();
}
}
JavaScript
// JavaScript program to encode a
// binary tree.
class Node {
constructor(x) {
this.data = x;
this.left = null;
this.right = null;
}
}
// Recursive pre-order function to
// encode a binary tree.
function encodeTreeRecur(root, s, arr) {
// For null nodes
if (root === null) {
s.push('0');
return;
}
s.push('1');
// Store pre-order in array.
arr.push(root.data);
// Apply pre-order to left and
// right subtree.
encodeTreeRecur(root.left, s, arr);
encodeTreeRecur(root.right, s, arr);
}
function encodeTree(root) {
let s = [];
let arr = [];
encodeTreeRecur(root, s, arr);
return [s.join(''), arr];
}
// Binary tree
// 10
// / \
// 20 30
// / \ \
// 40 50 70
let root = new Node(10);
root.left = new Node(20);
root.right = new Node(30);
root.left.left = new Node(40);
root.left.right = new Node(50);
root.right.right = new Node(70);
const ans = encodeTree(root);
console.log(ans[0]);
console.log(ans[1].join(" "));
Output1110010010100
10 20 40 50 30 70
Approach for decoding binary tree - O(n) Time and O(n) Space
The idea is to perform pre-order traversal of the string. If the current character is '0', return null. Otherwise create a new node with value equal to current element of the data array. Return the root node.
Below is the implementation of the above approach:
C++
// C++ program to decode a
// binary tree.
#include <bits/stdc++.h>
using namespace std;
class Node {
public:
int data;
Node *left, *right;
Node (int x) {
data = x;
left = nullptr;
right = nullptr;
}
};
// Recursive pre-order function to
// decode a binary tree.
Node* decodeTreeRecur(int &i, string &s, int &j, vector<int> &arr) {
// if s[i]==0, return null node
if (s[i] == '0') {
i++;
return nullptr;
}
// Create a new Node
Node* root = new Node(arr[j++]);
i++;
// Construct left and right subtree.
root->left = decodeTreeRecur(i,s,j,arr);
root->right = decodeTreeRecur(i,s,j,arr);
return root;
}
Node* decodeTree(string s, vector<int> arr) {
int i = 0, j = 0;
return decodeTreeRecur(i, s, j, arr);
}
void printInorder(Node* root) {
if (root == nullptr) return;
printInorder(root->left);
cout << root->data << " ";
printInorder(root->right);
}
int main() {
string s = "1110010010100";
vector<int> arr = {10, 20, 40, 50, 30, 70};
Node* root = decodeTree(s, arr);
printInorder(root);
return 0;
}
Java
// Java program to decode a
// binary tree.
import java.util.ArrayList;
class Node {
int data;
Node left, right;
Node(int x) {
data = x;
left = null;
right = null;
}
}
class GfG {
// Recursive pre-order function to
// decode a binary tree.
static Node decodeTreeRecur(int[] i, String s,
int[] j, ArrayList<Integer> arr) {
// if s[i]==0, return null node
if (s.charAt(i[0]) == '0') {
i[0]++;
return null;
}
// Create a new Node
Node root = new Node(arr.get(j[0]++));
i[0]++;
// Construct left and right subtree.
root.left = decodeTreeRecur(i, s, j, arr);
root.right = decodeTreeRecur(i, s, j, arr);
return root;
}
static Node decodeTree(String s,
ArrayList<Integer> arr) {
int[] i = {0}, j = {0};
return decodeTreeRecur(i, s, j, arr);
}
static void printInorder(Node root) {
if (root == null) return;
printInorder(root.left);
System.out.print(root.data + " ");
printInorder(root.right);
}
public static void main(String[] args) {
String s = "1110010010100";
ArrayList<Integer> arr = new ArrayList<>();
arr.add(10);
arr.add(20);
arr.add(40);
arr.add(50);
arr.add(30);
arr.add(70);
Node root = decodeTree(s, arr);
printInorder(root);
}
}
Python
# Python program to decode a
# binary tree.
class Node:
def __init__(self, x):
self.data = x
self.left = None
self.right = None
# Recursive pre-order function to
# decode a binary tree.
def decodeTreeRecur(i, s, j, arr):
# if s[i]==0, return null node
if s[i[0]] == '0':
i[0] += 1
return None
# Create a new Node
root = Node(arr[j[0]])
j[0] += 1
i[0] += 1
# Construct left and right subtree.
root.left = decodeTreeRecur(i, s, j, arr)
root.right = decodeTreeRecur(i, s, j, arr)
return root
def decodeTree(s, arr):
i = [0]
j = [0]
return decodeTreeRecur(i, s, j, arr)
def printInorder(root):
if root is None:
return
printInorder(root.left)
print(root.data, end=" ")
printInorder(root.right)
if __name__ == "__main__":
s = "1110010010100"
arr = [10, 20, 40, 50, 30, 70]
root = decodeTree(s, arr)
printInorder(root)
C#
// C# program to decode a
// binary tree.
using System;
using System.Collections.Generic;
class Node {
public int data;
public Node left, right;
public Node(int x) {
data = x;
left = null;
right = null;
}
}
class GfG {
// Recursive pre-order function to
// decode a binary tree.
static Node decodeTreeRecur(ref int i, string s,
ref int j, List<int> arr) {
// if s[i]==0, return null node
if (s[i] == '0') {
i++;
return null;
}
// Create a new Node
Node root = new Node(arr[j++]);
i++;
// Construct left and right subtree.
root.left = decodeTreeRecur(ref i, s, ref j, arr);
root.right = decodeTreeRecur(ref i, s, ref j, arr);
return root;
}
static Node decodeTree(string s, List<int> arr) {
int i = 0, j = 0;
return decodeTreeRecur(ref i, s, ref j, arr);
}
static void printInorder(Node root) {
if (root == null) return;
printInorder(root.left);
Console.Write(root.data + " ");
printInorder(root.right);
}
static void Main(string[] args) {
string s = "1110010010100";
List<int> arr = new List<int> {10, 20, 40, 50, 30, 70};
Node root = decodeTree(s, arr);
printInorder(root);
}
}
JavaScript
// JavaScript program to decode a
// binary tree.
class Node {
constructor(x) {
this.data = x;
this.left = null;
this.right = null;
}
}
// Recursive pre-order function to
// decode a binary tree.
function decodeTreeRecur(i, s, j, arr) {
// if s[i]==0, return null node
if (s[i[0]] === '0') {
i[0]++;
return null;
}
// Create a new Node
const root = new Node(arr[j[0]++]);
i[0]++;
// Construct left and right subtree.
root.left = decodeTreeRecur(i, s, j, arr);
root.right = decodeTreeRecur(i, s, j, arr);
return root;
}
function decodeTree(s, arr) {
let i = [0];
let j = [0];
return decodeTreeRecur(i, s, j, arr);
}
function printInorder(root) {
if (root === null) return;
printInorder(root.left);
console.log(root.data);
printInorder(root.right);
}
let s = "1110010010100";
let arr = [10, 20, 40, 50, 30, 70];
let root = decodeTree(s, arr);
printInorder(root);
Explore
DSA Fundamentals
Data Structures
Algorithms
Advanced
Interview Preparation
Practice Problem