বাইনারি ট্রি এনকোডিং


12

ধরা যাক আপনার একটি সম্পূর্ণ বাইনারি গাছ রয়েছে (অর্থাত্ প্রতিটি অভ্যন্তরীণ নোডে হ'ল দুটি খালি বংশধর রয়েছে)। প্রতিটি নোডে একটি ননজারো পূর্ণসংখ্যা থাকে। আপনাকে পূর্ণসংখ্যার একটি তালিকা থেকে / এ গাছটি এনকোডিং এবং ডিকোড করার কাজ দেওয়া হবে।

গাছটি অভ্যন্তরীণভাবে কিছু সঞ্চিত থাকে:

struct node {
  int data;
  struct node *left, *right;
};

এবং আপনাকে দুটি ফাংশন প্রয়োগ করতে হবে:

int *encode(struct node *root);
struct node *decode(int *array);

আপনি কীভাবে এনকোড এবং ডিকোড করবেন এটি আপনার উপর নির্ভর করে।

জন্য পয়েন্ট:

  • সর্বনিম্ন এনকোডিংয়ের দৈর্ঘ্য
  • জটিলতা (নোডের সংখ্যাতে আদর্শ রৈখিক)
  • মৌলিকত্ব

উত্স কোড দৈর্ঘ্যের জন্য কোন পয়েন্ট এবং আপনি সি এর মধ্যে সীমাবদ্ধ নন

গাছের উদাহরণ:

     5
    / \
   3   2
      / \
     2   1
    / \
   9   9

1
ইনপুট এবং আউটপুট প্রয়োজনীয়তা ক্ষতি করবে না।
ইয়াসির আরসানুকায়েভ

2
@ ইয়াসির: এনকোডিং অ্যালগরিদম আপনার কাজ তাই আমি কোনও ইনপুট এবং আউটপুট সরবরাহ করতে পারি না। int *ব্যবহারকারীর জন্য একটি কালো বাক্স।
আলেকজান্দ্রু

পূর্ণসংখ্যার ব্যাপ্তিতে কি কোনও বিধিনিষেধ রয়েছে? আরও সুনির্দিষ্টভাবে যদি আমরা যথেচ্ছভাবে বড় পূর্ণসংখ্যার সাথে কোন ভাষা ব্যবহার করি তবে আমাদের কি এটির ব্যবহারের অনুমতি দেওয়া হচ্ছে? এবং এনকোডড ডেটার আকারটি পূর্ণসংখ্যার সংখ্যা বা বাইটের সংখ্যায় পরিমাপ করা হয়?
sepp2k

এনকোড এবং ডিকোড ফাংশনগুলি কি পার্শ্ব-প্রভাব মুক্ত (মেমরি বরাদ্দ ব্যতীত) হওয়া দরকার? অথবা তারা উদাহরণস্বরূপ গ্লোবাল ভেরিয়েবলগুলিতে ডেটা সঞ্চয় করতে পারে?
sepp2k

1
উপাত্তটি পূর্ণসংখ্যাগুলি সত্যই 32-বিট পূর্ণসংখ্যা হিসাবে ধরে নেওয়া হয়, একটি সাধারণ এনকোডিং রয়েছে যা কেবল 32 * n বিট ব্যবহার করে।
আনন

উত্তর:


2

~ 1.03 এন

দেখে মনে হচ্ছে এখন পর্যন্ত সমস্ত উত্তর সঞ্চয় করতে কমপক্ষে 2 * এন * 32-বিট লাগবে। (ভাষাগুলিতে সমাধানগুলি ব্যতীত যা হ্যাজেল এবং রুবির সমাধানের মতো 32 বিটের চেয়ে বেশি পূর্ণসংখ্যার মানগুলিকে মঞ্জুরি দেয় - তবে যখনই ডেটা 16 কে এর বেশি হবে তখন এগুলি এনকোড করতে অতিরিক্ত বাইট নিতে চলেছে))

এখানে এমন একটি সমাধান রয়েছে যা কেবলমাত্র এন + সিলিং (N / 32) +1 ইনস স্টোরেজ নেয়। এটি বড় এন এর জন্য 1.03125 এন এ পৌঁছায় এবং 20 এর চেয়ে বড় এন এর জন্য এটি 1.1 এন এর নীচে।

ধারণাটি হ'ল প্রতিটি নোডের জন্য একটি অতিরিক্ত বিট সংরক্ষণ করা হবে যেখানে 1 টি "হ্যাজ চিলড্রেন"। এই বিটগুলি সামনে N / 32 শব্দগুলিতে প্যাক করা হয়েছে।

int* encodeHelper(Node* n, int* code, int* pos, int* flag)
{
   int hasKids = (n->left!=0);
   code[*flag/32]|=hasKids<<(*flag&31);
   *flag+=1;
   if (hasKids) bencodeHelper(n->left, code, pos, flag);
   code[*pos]=n->data;
   *pos+=1;
   if (hasKids) bencodeHelper(n->right, code, pos, flag);
   return code;
}

int* encode(Node* h, int* sizeOut)
{
   int nnodes=countNodes(h);
   int nflags = (int)ceil(nnodes/32.0);
   int pos=nflags+1;
   int flag=32;
   int* out;
   *sizeOut = 1+nnodes+nflags;
   out = calloc(*sizeOut, sizeof(int));
   if (!h) return out;
   out[0]=nflags+1; //store start of data
   return encodeHelper(h,out,&pos,&flag);
}

Node* decodeHelper(int* code, int* pos, int* flag)
{
   Node*n = calloc(1, sizeof(Node));
   int hasKids = code[*flag/32]>>(*flag&31)&1;
   *flag+=1;
   if (hasKids) n->left = bdecodeHelper(code, pos, flag);
   n->data = code[*pos];
   *pos+=1;
   if (hasKids) n->right = bdecodeHelper(code, pos, flag);
   return n;
}

Node* decode(int* code)
{
   int flag=32;
   int pos=code[0];
   if (!pos) return NULL;
   return decodeHelper(code, &pos, &flag);
}

(এখানে সম্পূর্ণ বাস্তবায়ন)


5

এই হাস্কেল প্রোগ্রামটি এন ইন্টিজারে এন নোডের একটি গাছ এনকোড করে। কৌশলটি হ'ল এটি নোডের ডেটা দ্বিগুণ করে এনকোড করে এবং তারপরে নিম্ন-অর্ডার বিটটি ব্যবহার করে এটি নির্দেশ করে যে এটি কোনও লিফ নোড, বা কোনও অভ্যন্তর নোড।

প্রযুক্তিগতভাবে, এখানে Parserমোনাদ ওভার-কিল, যেহেতু কেবলমাত্র একটি পার্সার তৈরি হয়েছে, decoderএবং আমি পার্সার চেইনিং যুক্তিটি সরাসরি সেখানে রাখতে পারতাম। তবে এইভাবে ডিকোডারটি খুব স্পষ্ট, এবং Parserএটি ছোট আকার সত্ত্বেও, একটি যুক্তিসঙ্গত সাধারণ পার্সিং ফ্রেমওয়ার্ক।

import Control.Monad (ap)

data Tree = Leaf Integer | Node Integer Tree Tree
  deriving (Eq, Show)

encode :: Tree -> [Integer]
encode (Leaf n)     = [n*2]
encode (Node n t u) = (n*2+1) : encode t ++ encode u

decode :: [Integer] -> Maybe Tree
decode = fullyParse decoder
  where
    decoder :: Parser Integer Tree
    decoder = do
      i <- next
      let n = i `div` 2
      if even i
        then return (Leaf n)
        else return (Node n) `ap` decoder `ap` decoder

-- A simple Parsing Monad
data Parser a b = P { runParser :: [a] -> Maybe (b, [a]) }

instance Monad (Parser a) where
  return a = P ( \ts -> Just (a, ts) )
  p >>= q  = P ( \ts -> runParser p ts >>= (\(v,ts') -> runParser (q v) ts') )
  fail _   = P ( const Nothing )

next :: Parser a a
next = P n
 where n (t:ts) = Just (t,ts)
       n _      = Nothing

fullyParse :: Parser a b -> [a] -> Maybe b
fullyParse p ts = runParser p ts >>= consumedResult
  where
    consumedResult (v,[]) = Just v
    consumedResult _      = Nothing

-- Example
main :: IO ()
main = do
    putStrLn $ "example:  " ++ show ex
    putStrLn $ "encoding: " ++ show encEx
    putStrLn $ "decoding: " ++ show decEx
    putStrLn $ "worked?   " ++ show worked
  where
    ex = Node 5
          (Leaf 3)
          (Node 2
            (Node 2
              (Leaf 9)
              (Leaf 9)
            )
            (Leaf 1)
          )
    encEx = encode ex
    decEx = decode encEx
    worked = maybe False (ex ==) decEx

এটি চালানো আপনি পান:

> runhaskell TreeEncoding.hs 
example:  Node 5 (Leaf 3) (Node 2 (Node 2 (Leaf 9) (Leaf 9)) (Leaf 1))
encoding: [11,6,5,5,18,18,2]
decoding: Just (Node 5 (Leaf 3) (Node 2 (Node 2 (Leaf 9) (Leaf 9)) (Leaf 1)))
worked?   True

4

সি তে

#include <stdlib.h>
#include <stdio.h>

struct Node;
typedef struct Node Node;

struct Node
{
    int   data;
    Node* left;
    Node* right;
};
/* Private Functions */
static int*  encodeNode(Node* tree, int* store);
static Node* decodeNode(int** store);

/* Public Functions */
Node*   newNode(int data,Node* left,Node* right);
void    deleteTree(Node* tree);
int     countNodesTree(Node* tree);
int*    encode(Node *tree);
Node*   decode(int* store);
void    printTree(Node* tree);

Node* newNode(int data,Node* left,Node* right)
{
    Node* result    = (Node*)malloc(sizeof(Node));
    result->data    = data;
    result->left    = left;
    result->right   = right;

    return result;
}

void deleteTree(Node* tree)
{
    if (tree == NULL)
    {   return;
    }

    deleteTree(tree->left);
    deleteTree(tree->right);
    free(tree);
}

int countNodesTree(Node* tree)
{
    if (tree == NULL)
    {   return 0;
    }

    return    countNodesTree(tree->left)
            + countNodesTree(tree->right)
            + 1;
}

void printTree(Node* tree)
{
    if (tree == NULL)
    {
        fprintf(stdout, "- ");
    }
    else
    {
        fprintf(stdout, "%d ", tree->data);
        printTree(tree->left);
        printTree(tree->right);
    }
};

এনকোড:

int* encode(Node *tree)
{
    int     nodeCount   = countNodesTree(tree);
    int*    result      = (int*)malloc(sizeof(int) * (nodeCount * 2 + 1));

    // Put the node count in the first element.
    // This makes it easy to also serialize this object for transport
    // i.e. you can put it in a file or a stream (socket) and easily recover it.
    result[0]           = nodeCount;
    encodeNode(tree, result + 1);
    return result;
}

int* encodeNode(Node* tree, int* store)
{
    if (tree != NULL)
    {
        store[0]    = tree->data;
        /*
         * Slight overkill. for this question.
         * But works and makes future enhancement easy
         */
        store[1]    = (tree->left  == NULL ? 0 : 1)
                    + (tree->right == NULL ? 0 : 2);
        store += 2;

        store       = encodeNode(tree->left,  store);
        store       = encodeNode(tree->right, store);
    }
    return store;
}

ডিকোড:

Node* decode(int* store)
{
    if (store == NULL)
    { fprintf(stderr, "Bad Input terminating: encode() always return non NULL\n");
      exit(1);
    }

    if (store[0] == 0)
    {
        return NULL;
    }

    store++;
    return decodeNode(&store);
}

Node* decodeNode(int** store)
{
    int     value   = (*store)[0];
    int     flag    = (*store)[1];
    (*store) += 2;

    Node*   left    = flag & 1 ? decodeNode(store) : NULL;
    Node*   right   = flag & 2 ? decodeNode(store) : NULL;

    return newNode(value, left, right);
}

প্রধান:

int main()
{
    Node*   t = newNode(5,
                        newNode(3, NULL, NULL),
                        newNode(2,
                                newNode(2,
                                        newNode(9, NULL, NULL),
                                        newNode(9, NULL, NULL)
                                       ),
                                newNode(1, NULL, NULL)
                               )
                       );

    printTree(t);
    fprintf(stdout,"\n");

    int*    e   = encode(t);
    Node*   d   = decode(e);
    printTree(d);
    fprintf(stdout,"\n");

    free(e);
    deleteTree(d);
    deleteTree(t);
}

বিঃদ্রঃ. প্রতিটি নোড দুটি পূর্ণসংখ্যা হিসাবে এনকোড করা হয় (নোডের গণনার জন্য একটি প্লাস)।
সুতরাং সরবরাহ করা গাছগুলি এর মতো এনকোড করে:

 7, 5, 3, 3, 0, 2, 3, 2, 3, 9, 0, 9, 0 1, 0
 ^  ^
 ^  ^ Node 1
 ^
 Count

3

রুবিতে, @ এমটিএনভিউমার্কের চেয়ে একই এনকোডিং সহ :

class Node
        def initialize(data, left = nil, right = nil)
                @data, @left, @right = data, left, right
        end

        def encode
                "%d %s %s" % [@data<<1|1, @left.encode, @right.encode]
        end

        class << self
                def decode(str)
                        _decode(str.split.map &:to_i)
                end

                private

                def _decode(a)
                        n = a.shift
                        if n & 1 == 1
                                Node.new(n>>1, _decode(a), _decode(a))
                        else
                                Leaf.new(n>>1)
                        end
                end
        end
end

class Leaf < Node
        def encode
                (@data<<1).to_s
        end
end

tree=Node.decode("11 6 5 5 18 18 2")
print tree.encode

ব্যয়টি নোডের প্রতি এক পূর্ণসংখ্যা ( data << 1 | has_childs):

11 6 5 5 18 18 2

বাহ - যে দেখতে হাতা এবং মার্জিত। যাইহোক, এটি কোন অ্যারের গ্রহণ করে না, তাই না?
ব্যবহারকারী অজানা

2

nনোড সহ একটি বাইনারি গাছ দেওয়া , এটি 2n + 1পূর্ণসংখ্যার তালিকায় এটি এনকোড করে । এনকোডিং এবং ডিকোডিং অ্যালগরিদম উভয়েরই O(n)জটিলতা রয়েছে।

এনকোডিংয়ের সময় আমি 0 পূর্ণসংখ্যাটি প্রেরককে চিহ্নিতকারী হিসাবে ব্যবহার করি, যখন আমি পুনরাবৃত্তিটি উদ্ঘাটন করি। তারপরে যখন আমি ডিকোডিং করছি, আমি গাছের নোডগুলি আমি একটি স্ট্যাকের (প্রকারের) তৈরি করছি এবং পরবর্তী নোডটি কোথায় যুক্ত করব তার ট্র্যাক রাখতে তালিকার 0s ব্যবহার করুন। আমি চেষ্টা করিনি, তবে আমি নিশ্চিত যে গাছটি সম্পূর্ণ না হলে ডিকোডিংটি ভেঙে যায়।

#include <math.h>
#include <stdio.h>
#include <stdlib.h>

// Prototypes
struct BTnode;
struct BTnode * bt_add_left(struct BTnode * node, int data);
struct BTnode * bt_add_right(struct BTnode * node, int data);
int             bt_depth(struct BTnode * tree);
int             bt_encode_preorder(int * list, struct BTnode * tree, int index);
struct BTnode * bt_node_create(int data);
int             bt_node_delete(struct BTnode * node);
void            bt_print_preorder(struct BTnode * tree);
int *           encode(struct BTnode * tree);
struct BTnode * decode(int * list);

// Binary tree node
struct BTnode
{
  int data;
  struct BTnode *left, *right;
};

// Add node to this node's left
struct BTnode * bt_add_left(struct BTnode * node, int data)
{
  struct BTnode * newnode = bt_node_create(data);
  node->left = newnode;
  return newnode;
}

// Add node to this node's right
struct BTnode * bt_add_right(struct BTnode * node, int data)
{
  struct BTnode * newnode = bt_node_create(data);
  node->right = newnode;
  return newnode;
}

// Determine depth of the tree
int bt_depth(struct BTnode * tree)
{
  int depth;
  int leftdepth = 0;
  int  rightdepth = 0;
  if( tree == NULL ) return 0;

  if( tree->left != NULL )
    leftdepth = bt_depth(tree->left);
  if( tree->right != NULL )
    rightdepth = bt_depth(tree->right);

  depth = leftdepth;
  if(rightdepth > leftdepth)
    depth = rightdepth;

  return depth + 1;
}

// Recursively add node values to integer list, using 0 as an unfolding sentinel
int bt_encode_preorder(int * list, struct BTnode * tree, int index)
{
  list[ index++ ] = tree->data;

  // This assumes the tree is complete (i.e., if the current node does not have
  // a left child, then it does not have a right child either)
  if( tree->left != NULL )
  {
    index = bt_encode_preorder(list, tree->left, index);
    index = bt_encode_preorder(list, tree->right, index);
  }

  // Add sentinel
  list[ index++ ] = 0;
  return index;
}

// Allocate memory for a node
struct BTnode * bt_node_create(int data)
{
  struct BTnode * newnode = (struct BTnode *) malloc(sizeof(struct BTnode));
  newnode->left = NULL;
  newnode->right = NULL;
  newnode->data = data;
  return newnode;
}

// Free node memory
int bt_node_delete(struct BTnode * node)
{
  int data;
  if(node == NULL)
    return 0;
  data = node->data;

  if(node->left != NULL)
    bt_node_delete(node->left);
  if(node->right != NULL)
    bt_node_delete(node->right);

  free(node);
  return data;
}

// Print all values from the tree in pre-order
void bt_print_preorder(struct BTnode * tree)
{
  printf("%d ", tree->data);
  if(tree->left != NULL)
    bt_print_preorder(tree->left);
  if(tree->right != NULL)
    bt_print_preorder(tree->right);
}

// Decode binary tree structure from a list of integers
struct BTnode * decode(int * list)
{
  struct BTnode * tree;
  struct BTnode * nodestack[ list[0] ];
  int i,j;

  // Handle trivial case
  if( list == NULL ) return NULL;

  tree = bt_node_create( list[1] );
  nodestack[ 1 ] = tree;

  j = 1;
  for(i = 2; i < list[0]; i++)
  {
    if( list[i] == 0 )
    {
      //printf("popping\n");
      j--;
    }
    else
    {
      if( nodestack[j]->left == NULL )
      {
        //printf("Adding %d to left of %d\n", list[i], nodestack[j]->data);
        nodestack[ j+1 ] = bt_add_left(nodestack[j], list[i]);
        j++;
      }
      else
      {
        //printf("Adding %d to right of %d\n", list[i], nodestack[j]->data);
        nodestack[ j+1 ] = bt_add_right(nodestack[j], list[i]);
        j++;
      }
    }
  }

  return tree;
}

// Encode binary tree structure as a list of integers
int * encode(struct BTnode * tree)
{
  int maxnodes, depth, length;
  int * list;
  int j;

  // Handle trivial case
  if(tree == NULL) return NULL;

  // Calculate maximum number of nodes in the tree from the tree depth
  maxnodes = 1;
  depth = bt_depth(tree);
  for(j = 0; j < depth; j++)
  {
    maxnodes += pow(2, j);
  }

  // Allocate memory for the list; we need two ints for each value plus the
  // first value in the list to indicate length
  list = (int *) malloc( ((maxnodes * 2)+1) * sizeof(int));
  length = bt_encode_preorder(list, tree, 1);
  list[ 0 ] = length;
  return list;
}

int main()
{
  struct BTnode * tree;
  struct BTnode * newtree;
  int * list;
  int i;

  /* Provided example

        5
       / \
      3   2
         / \
        2   1
       / \
      9   9
  */
  tree = bt_node_create(5);
  bt_add_left(tree, 3);
  struct BTnode * temp = bt_add_right(tree, 2);
  bt_add_right(temp, 1);
  temp = bt_add_left(temp, 2);
  bt_add_left(temp, 9);
  bt_add_right(temp, 9);
  printf("T (traversed in pre-order):  ");
  bt_print_preorder(tree);
  printf("\n");

  list = encode(tree);
  printf("T (encoded as integer list): ");
  for(i = 1; i < list[0]; i++)
    printf("%d ", list[i]);
  printf("\n");

  newtree = decode(list);
  printf("T' (decoded from int list):  ");
  bt_print_preorder(newtree);
  printf("\n\n");


  // Free memory
  bt_node_delete(tree);
  bt_node_delete(newtree);
  free(list);
  return 0;
}

encode.cসংকলন এবং কার্যকর হিসাবে এটি সংরক্ষণ করা। এই প্রোগ্রামটি আপনার প্রদান করা উদাহরণস্বরূপ গাছ ব্যবহার করে এবং আমি এটি সফলভাবে কয়েকজনের উপর পরীক্ষা করেছি।

$ gcc -Wall -lm -o encode encode.c
$ ./encode 
T (traversed in pre-order):  5 3 2 2 9 9 1 
T (encoded as integer list): 5 3 0 2 2 9 0 9 0 0 1 0 0 0 
T' (decoded from int list):  5 3 2 2 9 9 1

আমার মনে যা ছিল তা অনেকটাই :) :)
আলেকজান্দ্রু

যদি ডেটাতে 0 থাকে তবে এটি ডিকোডিংয়ে ব্যর্থ হবে না?
অ্যাশেলি

@ শ্যাশলি তিনি স্পষ্টতই বলেছিলেন যে 0 টি গাছে অন্তর্ভুক্ত করা হবে না। যদি এটি হয়, তবে হ্যাঁ এটি ব্যর্থ হবে।
ড্যানিয়েল স্ট্যান্ডেজ

2

আমার কোডটি গাছটিকে একটি প্রিআর্ডার ট্র্যাভারসাল এ এনকোড করে, প্রতিটি পাতাকে দুটি ইন্টিতে (এর ডেটা 0 এর পরে আসে) এবং প্রতিটি অভ্যন্তরীণ নোডকে একটি ইন্টে (তার ডেটা তার বাম শিশু অনুসরণ করে তার ডানদিকে)) একটি সম্পূর্ণ বাইনারি গাছের জন্য (যেমন আপনি এটি সংজ্ঞায়িত করেছেন) এন নোডগুলি সহ, অবশ্যই অবশ্যই বিজোড় হতে হবে এবং সেখানে (এন + 1) / 2 পাতা এবং (এন -1) / 2 অভ্যন্তরীণ নোড রয়েছে, সুতরাং এটি 3n / 2 + 1 / এনকোডিংয়ের জন্য 2 পূর্ণসংখ্যা।

সতর্কতা: অরক্ষিত, কেবল এটি টাইপ করুন।

struct node {
  int data;
  struct node *left, *right;
};

void encodeInternal(struct node *root, vector<int> *buf) {
  buf->push_back(root->data);
  if (root->left) {
    encodeInternal(root->left, buf);
    encodeInternal(root->right, buf);
  } else {
    buf->push_back(0);
  }
}
int *encode(struct node *root) {
  vector<int> buf;
  encodeInternal(root, &buf);
  return &buf[0];
}

struct decodeResult {
  int encoded_size;
  struct node *n;
}
struct decodeResult decodeInternal(int *array) {
  struct node *n = (struct node*)malloc(sizeof(struct node));
  n->data = array[0];
  if (array[1] == 0) {
    n->left = n->right = NULL;
    return (decodeResult){2, n};
  } else {
    decodeResult L = decodeInternal(array + 1);
    decodeResult R = decodeInternal(array + 1 + L.encoded_size);
    n->left = L.n;
    n->right = R.n;
    return (decodeResult){1 + L.encoded_size + R.encoded_size, n};
  }
}
struct node *decode(int *array) {
  return decodeInternal(array).n;
}

1

এখানে আমার চেষ্টা। এটি গাছের আকার 2 ** গভীরতা + 1 এর অ্যারে সংরক্ষণ করে। এটি a[0]আকার a[size]ধারণ করতে এবং প্রথম "খালি নোড" এর সূচকটি ধরে রাখার জন্য এটি গভীরতার সাথে প্রথম ট্র্যাভারসাল সম্মুখীন হয়। (একটি খালি নোড এমন একটি জায়গা যেখানে পিতা বা মাতা থাকলে একটি শিশু সংরক্ষণ করা হত)। প্রতিটি খালি নোডের পরবর্তী খালি নোডের সূচক থাকে যা মুখোমুখি হবে।

এই স্কিমটি উপস্থাপিত শিশুদের চিহ্নিত করতে বিটগুলি সংরক্ষণ করা এড়িয়ে চলে, তাই প্রতিটি নোড পূর্ণ সংখ্যার ব্যাপ্তি ব্যবহার করতে পারে। এটি ভারসাম্যহীন গাছগুলিকেও মঞ্জুরি দেয় - একটি পিতামাতার কেবল একটি সন্তান থাকতে পারে।

আউটপুট:

empty tree:  [0]
head node only:  [2,5,0]
example tree: [16,5,3,2,5,14,2,1,0,0, 0,0,9,9,15,0,4];

এনকোডার:

//utility
 int findDepth(Node* n) {
    int l = 0 ,r = 0;
    if (n) {
       l = 1 + findDepth(n->left);
       r = 1 + findDepth(n->right);
    }
    return ( l > r ) ? l : r;
 }

//Encode Function
 int* encodeTree(Node* head) {
    int* out;
    int depth = findDepth(head);
    int size = depth>0;
    while (depth--) size*=2;
    out = calloc(size+1,sizeof(int));
    out[0]=size;
    encodeNode(head, out,1, out+size);
    return out;
 }

 void encodeNode(Node* n, int* a, int idx, int* pEmpty) {
    if (n) {
       a[idx]=n->data;
       encodeNode(n->left,a,idx*2,pEmpty);
       encodeNode(n->right,a,idx*2+1,pEmpty);
    }
    else if (idx<a[0]) {
       *pEmpty = idx;
       pEmpty = a+idx;
    }
 }

ডিকোডার:

 //Decode Function
 Node* decodeArray(int* a) {
    return (a[0]) ?  decodeNode(a,1,a+a[0]) : NULL;
 }

 Node* decodeNode(int* a, int idx, int* pEmpty) {
    Node* n = NULL;
    if (idx== *pEmpty)
       *pEmpty=a[idx];
    else {
       n = calloc(1,sizeof(Node));
       n->data = a[idx];
       if (idx*2<a[0]) {
          n->left = decodeNode(a, idx*2, pEmpty);
          n->right = decodeNode(a, idx*2+1, pEmpty);
       }
    }
    return n;
 }

(বিন্যাস ঠিক করার জন্য ধন্যবাদ @ ডানিয়েল সোব্রাল)


1

scala:

trait Node {
  def encode (): Array[Int]
}

case object Node {
  def decode (a: Array[Int]): InnerNode = {
    if (a.length == 1) InnerNode (a(0)) else {
      val r = InnerNode (a(1)) 
      val l = decode (a.tail.tail) 
      InnerNode (a(0), l, r) 
    }
  }
}

case object Leaf extends Node {
  def encode (): Array[Int] = Array.empty
}

case class InnerNode (val data: Int, var l: Node=Leaf, var r: Node=Leaf) extends Node {
  def encode (): Array[Int] = Array (data) ++ r.encode () ++ l.encode () 
}

object BinTreeTest extends App {
  println (Node.decode (Array (1, 2, 3, 4, 5)).encode.mkString (", "))
}

এটি এমন একটি দৃষ্টিভঙ্গি যা অবনমিত সিনট্যাক্স ব্যবহার করে তবে স্কেলা ২.৯.১ এ ত্রুটি ছাড়াই সংকলন করে। এটি একটি ট্রি উত্পন্ন করে এবং এনকোডিংয়ের জন্য ব্যবহৃত প্রতিটি অ্যারেঙ্কড ট্রিটিকে একই অ্যারে ডিকোড করে। আজ আমি হতাশ সতর্কতাগুলি থেকে কোনওভাবে মুক্তি পেতে পারি।

বাহ - এটি একটি সহজ ছিল। প্রথম ধারণা অবিলম্বে কাজ করে।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.