Open In App

Succinct Encoding of Binary Tree

Last Updated : 23 Jul, 2025
Suggest changes
Share
4 Likes
Like
Report

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:

45

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(" ")); 

Output
1110010010100 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); 

Output
40 20 50 10 30 70 

Article Tags :

Explore