Succinct Encoding of Binary Tree

28 Jun, 2022
A succinct encoding of Binary Tree takes close to 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 4 n = 2n bits to encode it. A succinct binary tree therefore would occupy 2n+o(n) bits.
One simple representation which meets this bound is to visit the nodes of the tree in preorder, outputting “1” for an internal node and “0” for a leaf. If the tree contains data, we can simply simultaneously store it in a consecutive array in preorder.
Below is algorithm for encoding: 
function EncodeSuccinct(node n, bitstring structure, array data) {
    if n = nil then
        append 0 to structure;
    else
        append 1 to structure;
        append n.data to data;
        EncodeSuccinct(n.left, structure, data);
        EncodeSuccinct(n.right, structure, data);
}
And below is algorithm for decoding 
function DecodeSuccinct(bitstring structure, array data) {
    remove first bit of structure and put it in b
    if b = 1 then
        create a new node n
        remove first element of data and put it in n.data
        n.left = DecodeSuccinct(structure, data)
        n.right = DecodeSuccinct(structure, data)
        return n
    else
        return nil
}
Example: 
Input:   
        10
     /      \
   20       30
  /  \        \
 40   50      70 

Data Array (Contains preorder traversal)
10 20 40 50 30 70

Structure Array
1 1 1 0 0 1 0 0 1 0 1 0 0 
1 indicates data and 0 indicates NULL
Below is the implementation of above algorithms.
C++
Java
Python3
C#
Javascript
// C++ program to demonstrate Succinct Tree Encoding and decoding#include<bits/stdc++.h>using namespace std; // A Binary Tree Nodestruct Node{    int key;    struct Node* left, *right;}; // Utility function to create new NodeNode *newNode(int key){    Node *temp = new Node;    temp->key  = key;    temp->left  = temp->right = NULL;    return (temp);} // This function fills lists 'struc' and 'data'.  'struc' list// stores structure information. 'data' list stores tree datavoid EncodeSuccinct(Node *root, list<bool> &struc, list<int> &data){    // If root is NULL, put 0 in structure array and return    if (root == NULL)    {        struc.push_back(0);        return;    }     // Else place 1 in structure array, key in 'data' array    // and recur for left and right children    struc.push_back(1);    data.push_back(root->key);    EncodeSuccinct(root->left, struc, data);    EncodeSuccinct(root->right, struc, data);} // Constructs tree from 'struc' and 'data'Node *DecodeSuccinct(list<bool> &struc, list<int> &data){    if (struc.size() <= 0)        return NULL;     // Remove one item from structure list    bool b = struc.front();    struc.pop_front();     // If removed bit is 1,    if (b == 1)    {         // remove an item from data list        int key = data.front();        data.pop_front();         // Create a tree node with the removed data        Node *root = newNode(key);         // And recur to create left and right subtrees        root->left = DecodeSuccinct(struc, data);        root->right = DecodeSuccinct(struc, data);        return root;    }     return NULL;} // A utility function to print treevoid preorder(Node* root){    if (root)    {        cout << "key: "<< root->key;        if (root->left)            cout << " | left child: " << root->left->key;        if (root->right)            cout << " | right child: " << root->right->key;        cout << endl;        preorder(root->left);        preorder(root->right);    }} // Driver programint main(){    // Let us construct the Tree shown in the above figure    Node *root         = newNode(10);    root->left         = newNode(20);    root->right        = newNode(30);    root->left->left   = newNode(40);    root->left->right  = newNode(50);    root->right->right = newNode(70);     cout << "Given Tree\n";    preorder(root);    list<bool> struc;    list<int>  data;    EncodeSuccinct(root, struc, data);     cout << "\nEncoded Tree\n";    cout << "Structure List\n";    list<bool>::iterator si; // Structure iterator    for (si = struc.begin(); si != struc.end(); ++si)        cout << *si << " ";     cout << "\nData List\n";    list<int>::iterator di; // Data iIterator    for (di = data.begin(); di != data.end(); ++di)        cout << *di << " ";     Node *newroot = DecodeSuccinct(struc, data);     cout << "\n\nPreorder traversal of decoded tree\n";    preorder(newroot);     return 0;}
// Java program to demonstrate Succinct// Tree Encoding and decodingimport java.util.*; class GFG{ // A Binary Tree Nodestatic class Node{    int key;    Node left, right;}; // Utility function to create new Nodestatic Node newNode(int key){    Node temp = new Node();    temp.key  = key;    temp.left  = temp.right = null;    return (temp);} static Vector<Boolean> struc;static Vector<Integer> data;static Node root; // This function fills lists 'struc' and// 'data'. 'struc' list stores structure// information. 'data' list stores tree datastatic void EncodeSuccinct(Node root){         // If root is null, put 0 in    // structure array and return    if (root == null)    {        struc.add(false);        return;    }     // Else place 1 in structure array,    // key in 'data' array and recur    // for left and right children    struc.add(true);    data.add(root.key);    EncodeSuccinct(root.left);    EncodeSuccinct(root.right);} // Constructs tree from 'struc' and 'data'static Node DecodeSuccinct(){    if (struc.size() <= 0)        return null;     // Remove one item from structure list    boolean b = struc.get(0);    struc.remove(0);     // If removed bit is 1,    if (b == true)    {                 // Remove an item from data list        int key = data.get(0);        data.remove(0);         // Create a tree node with the        // removed data        Node root = newNode(key);         // And recur to create left and        // right subtrees        root.left = DecodeSuccinct();        root.right = DecodeSuccinct();        return root;    }    return null;} // A utility function to print treestatic void preorder(Node root){    if (root != null)    {        System.out.print("key: "+ root.key);        if (root.left != null)            System.out.print(" | left child: " +                              root.left.key);        if (root.right != null)            System.out.print(" | right child: " +                              root.right.key);        System.out.println();                 preorder(root.left);        preorder(root.right);    }} // Driver codepublic static void main(String[] args){         // Let us construct Tree shown in    // the above figure    Node root = newNode(10);    root.left = newNode(20);    root.right = newNode(30);    root.left.left = newNode(40);    root.left.right = newNode(50);    root.right.right = newNode(70);     System.out.print("Given Tree\n");    preorder(root);    struc = new Vector<>();    data = new Vector<>();    EncodeSuccinct(root);     System.out.print("\nEncoded Tree\n");    System.out.print("Structure List\n");      for(boolean  si : struc)    {        if (si == true)            System.out.print(1 + " ");        else            System.out.print(0 + " ");    }     System.out.print("\nData List\n");    for(int di : data)        System.out.print(di + " ");     Node newroot = DecodeSuccinct();     System.out.print("\n\nPreorder traversal" +                     "of decoded tree\n");                          preorder(newroot);}} // This code is contributed by aashish1995
# Python program to demonstrate Succinct Tree Encoding and Decoding # Node structureclass Node:    # Utility function to create new Node    def __init__(self , key):        self.key = key        self.left = None        self.right = None def EncodeSuccinct(root , struc , data):         # If root is None , put 0 in structure array and return    if root is None :        struc.append(0)        return     # Else place 1 in structure array, key in 'data' array    # and recur for left and right children    struc.append(1)    data.append(root.key)    EncodeSuccinct(root.left , struc , data)    EncodeSuccinct(root.right , struc ,data)      # Constructs tree from 'struc' and 'data'def DecodeSuccinct(struc , data):    if(len(struc) <= 0):        return None         # Remove one item from structure list    b = struc[0]    struc.pop(0)         # If removed bit is 1    if b == 1:        key = data[0]        data.pop(0)             #Create a tree node with removed data        root = Node(key)         #And recur to create left and right subtrees        root.left = DecodeSuccinct(struc , data);        root.right = DecodeSuccinct(struc , data);        return root     return None  def preorder(root):    if root is not None:        print ("key: %d" %(root.key),end=" ")                     if root.left is not None:            print ("| left child: %d" %(root.left.key),end=" ")        if root.right is not None:            print ("| right child %d" %(root.right.key),end=" ")        print ()        preorder(root.left)        preorder(root.right) # Driver Programroot = 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)         print ("Given Tree")preorder(root)struc = []data = []EncodeSuccinct(root , struc , data) print ("\nEncoded Tree")print ("Structure List") for i in struc:    print (i ,end=" ") print ("\nDataList")for value in data:    print (value,end=" ") newroot = DecodeSuccinct(struc , data) print ("\n\nPreorder Traversal of decoded tree")preorder(newroot) # This code is contributed by Nikhil Kumar Singh(nickzuck_007)
// C# program to demonstrate Succinct// Tree Encoding and decodingusing System;using System.Collections.Generic;class GFG{   // A Binary Tree Node  public    class Node    {      public        int key;      public        Node left, right;    };   // Utility function to create new Node  static Node newNode(int key)  {    Node temp = new Node();    temp.key  = key;    temp.left  = temp.right = null;    return (temp);  }  static List<Boolean> struc;  static List<int> data;  static Node root;   // This function fills lists 'struc' and  // 'data'. 'struc' list stores structure  // information. 'data' list stores tree data  static void EncodeSuccinct(Node root)  {     // If root is null, put 0 in    // structure array and return    if (root == null)    {      struc.Add(false);      return;    }     // Else place 1 in structure array,    // key in 'data' array and recur    // for left and right children    struc.Add(true);    data.Add(root.key);    EncodeSuccinct(root.left);    EncodeSuccinct(root.right);  }   // Constructs tree from 'struc' and 'data'  static Node DecodeSuccinct()  {    if (struc.Count <= 0)      return null;     // Remove one item from structure list    bool b = struc[0];    struc.RemoveAt(0);     // If removed bit is 1,    if (b == true)    {       // Remove an item from data list      int key = data[0];      data.Remove(0);       // Create a tree node with the      // removed data      Node root = newNode(key);       // And recur to create left and      // right subtrees      root.left = DecodeSuccinct();      root.right = DecodeSuccinct();      return root;    }    return null;  }   // A utility function to print tree  static void preorder(Node root)  {    if (root != null)    {      Console.Write("key: "+ root.key);      if (root.left != null)        Console.Write(" | left child: " +                       root.left.key);      if (root.right != null)        Console.Write(" | right child: " +                       root.right.key);      Console.WriteLine();      preorder(root.left);      preorder(root.right);    }  }   // Driver code  public static void Main(String[] args)  {     // Let us construct Tree shown in    // the above figure    Node root = newNode(10);    root.left = newNode(20);    root.right = newNode(30);    root.left.left = newNode(40);    root.left.right = newNode(50);    root.right.right = newNode(70);    Console.Write("Given Tree\n");    preorder(root);    struc = new List<Boolean>();    data = new List<int>();    EncodeSuccinct(root);    Console.Write("\nEncoded Tree\n");    Console.Write("Structure List\n");    foreach(bool  si in struc)    {      if (si == true)        Console.Write(1 + " ");      else        Console.Write(0 + " ");    }     Console.Write("\nData List\n");    foreach(int di in data)      Console.Write(di + " ");    Node newroot = DecodeSuccinct();    Console.Write("\n\nPreorder traversal" +                  "of decoded tree\n");                        preorder(newroot);  }} // This code is contributed by gauravrajput1
<script> // Javascript program to demonstrate Succinct// Tree Encoding and decoding// A Binary Tree Nodeclass Node{  constructor()  {    this.key = 0;    this.left = null;    this.right = null;  }}; // Utility function to create new Nodefunction newNode(key){  var temp = new Node();  temp.key  = key;  temp.left  = temp.right = null;  return (temp);} var struc = [];var data = [];var root = null; // This function fills lists 'struc' and// 'data'. 'struc' list stores structure// information. 'data' list stores tree datafunction EncodeSuccinct(root){   // If root is null, put 0 in  // structure array and return  if (root == null)  {    struc.push(false);    return;  }     // Else place 1 in structure array,  // key in 'data' array and recur  // for left and right children  struc.push(true);  data.push(root.key);  EncodeSuccinct(root.left);  EncodeSuccinct(root.right);} // Constructs tree from 'struc' and 'data'function DecodeSuccinct(){  if (struc.length <= 0)    return null;       // Remove one item from structure list  var b = struc[0];  struc.shift(0);     // If removed bit is 1,  if (b == true)  {       // Remove an item from data list    var key = data[0];    data.shift();         // Create a tree node with the    // removed data    var root = newNode(key);         // And recur to create left and    // right subtrees    root.left = DecodeSuccinct();    root.right = DecodeSuccinct();    return root;  }  return null;} // A utility function to print treefunction preorder(root){  if (root != null)  {    document.write("key: "+ root.key);    if (root.left != null)      document.write(" | left child: " +                     root.left.key);    if (root.right != null)      document.write(" | right child: " +                     root.right.key);    document.write("<br>");    preorder(root.left);    preorder(root.right);  }} // Driver code// Let us construct Tree shown in// the above figurevar root = newNode(10);root.left = newNode(20);root.right = newNode(30);root.left.left = newNode(40);root.left.right = newNode(50);root.right.right = newNode(70);document.write("Given Tree<br>");preorder(root);struc = [];data = [];EncodeSuccinct(root);document.write("<br>Encoded Tree<br>");document.write("Structure List<br>");for(var si of struc){  if (si == true)    document.write(1 + " ");  else    document.write(0 + " ");}document.write("<br>Data List<br>");for(var di of data)  document.write(di + " ");var newroot = DecodeSuccinct();document.write("<br><br>Preorder traversal" +              "of decoded tree<br>");                    preorder(newroot); // This code is contributed by rrrtnx.</script>
Given Tree
key: 10 | left child: 20 | right child: 30
key: 20 | left child: 40 | right child: 50
key: 40
key: 50
key: 30 | right child: 70
key: 70

Encoded Tree
Structure List
1 1 1 0 0 1 0 0 1 0 1 0 0 
Data List
10 20 40 50 30 70 

Preorder traversal of decoded tree
key: 10 | left child: 20 | right child: 30
key: 20 | left child: 40 | right child: 50
key: 40
key: 50
key: 30 | right child: 70
key: 70

Akanksha_Rai
aashish1995
GauravRajput1
rrrtnx
sagartomar9927
amartyaghoshgfg
simmytarika5
hardikkoriintern
catalan
Tree
Tree
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
Tree Traversals (Inorder, Preorder and Postorder)
Binary Tree | Set 1 (Introduction)
Level Order Binary Tree Traversal
AVL Tree | Set 1 (Insertion)
Introduction to Data Structures
Introduction to Tree Data Structure
Inorder Tree Traversal without Recursion
What is Data Structure: Types, Classifications and Applications
Write a Program to Find the Maximum Depth or Height of a Tree
Binary Tree | Set 3 (Types of Binary Tree)