Skip to content
Related Articles
Get the best out of our app
GFG App
Open App
geeksforgeeks
Browser
Continue

Related Articles

Succinct Encoding of Binary Tree

Improve Article
Save Article
Like Article
Improve Article
Save Article
Like Article

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++




// C++ program to demonstrate Succinct Tree Encoding and decoding
#include<bits/stdc++.h>
using namespace std;
 
// A Binary Tree Node
struct Node
{
    int key;
    struct Node* left, *right;
};
 
// Utility function to create new Node
Node *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 data
void 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 tree
void 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 program
int 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 iterator
    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




// Java program to demonstrate Succinct
// Tree Encoding and decoding
import java.util.*;
 
class GFG{
 
// A Binary Tree Node
static class Node
{
    int key;
    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 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 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.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 tree
static 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 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);
 
    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


Python3




# Python program to demonstrate Succinct Tree Encoding and Decoding
 
# Node structure
class 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 Program
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)        
 
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#




// C# program to demonstrate Succinct
// Tree Encoding and decoding
using 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


Javascript




<script>
 
// Javascript program to demonstrate Succinct
// Tree Encoding and decoding
// A Binary Tree Node
class Node
{
  constructor()
  {
    this.key = 0;
    this.left = null;
    this.right = null;
  }
};
 
// Utility function to create new Node
function 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 data
function 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 tree
function 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 figure
var 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>


Output

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

 Time complexity: O(n)  
Auxiliary space: O(n).


My Personal Notes arrow_drop_up
Last Updated : 22 Dec, 2022
Like Article
Save Article
Similar Reads
Related Tutorials