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>usingnamespacestd;classNode{public:intdata;Node*left,*right;Node(intx){data=x;left=nullptr;right=nullptr;}};// Recursive pre-order function to // encode a binary tree.voidencodeTreeRecur(Node*root,string&s,vector<int>&arr){// For null nodesif(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){strings="";vector<int>arr;encodeTreeRecur(root,s,arr);returnmake_pair(s,arr);}intmain(){// Binary tree // 10// / \ // 20 30 // / \ \ // 40 50 70Node*root=newNode(10);root->left=newNode(20);root->right=newNode(30);//root->left->left = new Node(40); //root->left->right = new Node(50); root->right->right=newNode(70);pair<string,vector<int>>ans=encodeTree(root);cout<<ans.first<<endl;for(autonum:ans.second)cout<<num<<" ";cout<<endl;return0;}
Java
// Java program to encode a // binary tree.importjava.util.ArrayList;importjava.util.List;classNode{intdata;Nodeleft,right;Node(intx){data=x;left=null;right=null;}}classPair{Strings;ArrayList<Integer>arr;Pair(Strings1,ArrayList<Integer>arr1){s=s1;arr=arr1;}}classGfG{// Recursive pre-order function to // encode a binary tree.staticvoidencodeTreeRecur(Noderoot,StringBuilders,ArrayList<Integer>arr){// For null nodesif(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);}staticPairencodeTree(Noderoot){StringBuilders=newStringBuilder();ArrayList<Integer>arr=newArrayList<>();encodeTreeRecur(root,s,arr);returnnewPair(s.toString(),arr);}publicstaticvoidmain(String[]args){// Binary tree // 10// / \ // 20 30 // / \ \// 40 50 70Noderoot=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);Pairans=encodeTree(root);System.out.println(ans.s);for(intnum:ans.arr)System.out.print(num+" ");System.out.println();}}
Python
# Python program to encode a # binary tree.classNode:def__init__(self,x):self.data=xself.left=Noneself.right=None# Recursive pre-order function to # encode a binary tree.defencodeTreeRecur(root,s,arr):# For null nodesifrootisNone:s.append('0')returns.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)defencodeTree(root):s=[]arr=[]encodeTreeRecur(root,s,arr)return''.join(s),arrif__name__=="__main__":# Binary tree # 10# / \ # 20 30 # / \ \# 40 50 70root=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])fornuminans[1]:print(num,end=" ")print()
C#
// C# program to encode a // binary tree.usingSystem;usingSystem.Collections.Generic;classNode{publicintdata;publicNodeleft,right;publicNode(intx){data=x;left=null;right=null;}}classGfG{// Recursive pre-order function to // encode a binary tree.staticvoidencodeTreeRecur(Noderoot,refstrings,List<int>arr){// For null nodesif(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,refs,arr);encodeTreeRecur(root.right,refs,arr);}staticTuple<string,List<int>>encodeTree(Noderoot){strings="";List<int>arr=newList<int>();encodeTreeRecur(root,refs,arr);returnnewTuple<string,List<int>>(s,arr);}staticvoidMain(string[]args){// Binary tree // 10// / \ // 20 30 // / \ \// 40 50 70Noderoot=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);Tuple<string,List<int>>ans=encodeTree(root);Console.WriteLine(ans.Item1);foreach(intnuminans.Item2)Console.Write(num+" ");Console.WriteLine();}}
JavaScript
// JavaScript program to encode a // binary tree.classNode{constructor(x){this.data=x;this.left=null;this.right=null;}}// Recursive pre-order function to // encode a binary tree.functionencodeTreeRecur(root,s,arr){// For null nodesif(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);}functionencodeTree(root){lets=[];letarr=[];encodeTreeRecur(root,s,arr);return[s.join(''),arr];}// Binary tree // 10// / \ // 20 30 // / \ \// 40 50 70letroot=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);constans=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>usingnamespacestd;classNode{public:intdata;Node*left,*right;Node(intx){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 nodeif(s[i]=='0'){i++;returnnullptr;}// Create a new NodeNode*root=newNode(arr[j++]);i++;// Construct left and right subtree.root->left=decodeTreeRecur(i,s,j,arr);root->right=decodeTreeRecur(i,s,j,arr);returnroot;}Node*decodeTree(strings,vector<int>arr){inti=0,j=0;returndecodeTreeRecur(i,s,j,arr);}voidprintInorder(Node*root){if(root==nullptr)return;printInorder(root->left);cout<<root->data<<" ";printInorder(root->right);}intmain(){strings="1110010010100";vector<int>arr={10,20,40,50,30,70};Node*root=decodeTree(s,arr);printInorder(root);return0;}
Java
// Java program to decode a // binary tree.importjava.util.ArrayList;classNode{intdata;Nodeleft,right;Node(intx){data=x;left=null;right=null;}}classGfG{// Recursive pre-order function to // decode a binary tree.staticNodedecodeTreeRecur(int[]i,Strings,int[]j,ArrayList<Integer>arr){// if s[i]==0, return null nodeif(s.charAt(i[0])=='0'){i[0]++;returnnull;}// Create a new NodeNoderoot=newNode(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);returnroot;}staticNodedecodeTree(Strings,ArrayList<Integer>arr){int[]i={0},j={0};returndecodeTreeRecur(i,s,j,arr);}staticvoidprintInorder(Noderoot){if(root==null)return;printInorder(root.left);System.out.print(root.data+" ");printInorder(root.right);}publicstaticvoidmain(String[]args){Strings="1110010010100";ArrayList<Integer>arr=newArrayList<>();arr.add(10);arr.add(20);arr.add(40);arr.add(50);arr.add(30);arr.add(70);Noderoot=decodeTree(s,arr);printInorder(root);}}
Python
# Python program to decode a # binary tree.classNode:def__init__(self,x):self.data=xself.left=Noneself.right=None# Recursive pre-order function to # decode a binary tree.defdecodeTreeRecur(i,s,j,arr):# if s[i]==0, return null nodeifs[i[0]]=='0':i[0]+=1returnNone# Create a new Noderoot=Node(arr[j[0]])j[0]+=1i[0]+=1# Construct left and right subtree.root.left=decodeTreeRecur(i,s,j,arr)root.right=decodeTreeRecur(i,s,j,arr)returnrootdefdecodeTree(s,arr):i=[0]j=[0]returndecodeTreeRecur(i,s,j,arr)defprintInorder(root):ifrootisNone:returnprintInorder(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.usingSystem;usingSystem.Collections.Generic;classNode{publicintdata;publicNodeleft,right;publicNode(intx){data=x;left=null;right=null;}}classGfG{// Recursive pre-order function to // decode a binary tree.staticNodedecodeTreeRecur(refinti,strings,refintj,List<int>arr){// if s[i]==0, return null nodeif(s[i]=='0'){i++;returnnull;}// Create a new NodeNoderoot=newNode(arr[j++]);i++;// Construct left and right subtree.root.left=decodeTreeRecur(refi,s,refj,arr);root.right=decodeTreeRecur(refi,s,refj,arr);returnroot;}staticNodedecodeTree(strings,List<int>arr){inti=0,j=0;returndecodeTreeRecur(refi,s,refj,arr);}staticvoidprintInorder(Noderoot){if(root==null)return;printInorder(root.left);Console.Write(root.data+" ");printInorder(root.right);}staticvoidMain(string[]args){strings="1110010010100";List<int>arr=newList<int>{10,20,40,50,30,70};Noderoot=decodeTree(s,arr);printInorder(root);}}
JavaScript
// JavaScript program to decode a // binary tree.classNode{constructor(x){this.data=x;this.left=null;this.right=null;}}// Recursive pre-order function to // decode a binary tree.functiondecodeTreeRecur(i,s,j,arr){// if s[i]==0, return null nodeif(s[i[0]]==='0'){i[0]++;returnnull;}// Create a new Nodeconstroot=newNode(arr[j[0]++]);i[0]++;// Construct left and right subtree.root.left=decodeTreeRecur(i,s,j,arr);root.right=decodeTreeRecur(i,s,j,arr);returnroot;}functiondecodeTree(s,arr){leti=[0];letj=[0];returndecodeTreeRecur(i,s,j,arr);}functionprintInorder(root){if(root===null)return;printInorder(root.left);console.log(root.data);printInorder(root.right);}lets="1110010010100";letarr=[10,20,40,50,30,70];letroot=decodeTree(s,arr);printInorder(root);