二叉树的简洁编码
二叉树的简洁编码几乎占用了最小的可能空间。 n 个节点上结构不同的二叉树的数量是第 n 个加泰罗尼亚数。对于较大的 n,这大约是 4 n ;因此我们至少需要大约 log 2 4 n = 2n 位来对其进行编码。因此,一棵简洁的二叉树将占用 2n+o(n) 位。
满足这个界限的一个简单表示是按顺序访问树的节点,输出“1”表示内部节点,“0”表示叶子。如果树包含数据,我们可以简单地将其同时存储在一个连续的数组中。
下面是编码算法:
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);
}
下面是解码算法
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
}
资料来源:https://en.wikipedia.org/wiki/Binary_tree#Succinct_encodings
例子:
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
下面是上述算法的实现。
C++
// C++ program to demonstrate Succinct Tree Encoding and decoding
#include
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 &struc, list &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 &struc, list &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 struc;
list data;
EncodeSuccinct(root, struc, data);
cout << "\nEncoded Tree\n";
cout << "Structure List\n";
list::iterator si; // Structure iterator
for (si = struc.begin(); si != struc.end(); ++si)
cout << *si << " ";
cout << "\nData List\n";
list::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
// 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 struc;
static Vector 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 struc;
static List 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();
data = new List();
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
输出:
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