C : custom low-level data mapping - no strings, no recursion, no built-in DS - simple n short
Context : This solution of mine uses a custom low-level raw data mapping representaion. There is no string parsing involved, no recursive approach is being used
**Context :** This solution of mine uses a custom low-level raw data mapping representaion. There is no string parsing involved, no recursive approach is being used, and no built-in Data Structures are used. I have kept this code like all of my other published code as barebone C code as possible.\n\n**Details :** Before arriving at below custom data representation, I gave the string approach a try and was way slower due to the overhead in parsing, etc. So, I decided to redesign this in terms of my own custom data representation. In this representation, each of the node\'s address\'s LS-16bits act as key which get mapped onto unique 1-indexed numbers. These mapped indexes are then used as offsets for each of those nodes. Each node will refer to its child nodes using those offsets. Each node in the sequence of such nodes will hold the value of a specific node and its left-child-off and right-child-off. It took considerable time to get to this far but I feel it\'s totally worth it!\n\n**NOTE :** My below solution works for both BST and Binary Tree as there is no dependency on the structure or organization of the nodes or values therin. Just choose the key/mask width as per the address-range(LS-bits) of node addresses. As I observed, for the other Binary Tree case, I had to consider at least 17 lower bits of node addresses for their unique mapping whereas for the below BST, 16 lower bits were sufficient. Hence, I use appropriate width for key type as uint32_t(for 17-bits case) and uint16_t(for 16-bits case) controlled by WIDE_RANGE feature macro.\n\n```\n//#define WIDE_RANGE\n\n#ifdef WIDE_RANGE\n#define KEY_MASK    0x1ffff\ntypedef uint32_t keyy_t;\n#else\n#define KEY_MASK    0xffff\ntypedef uint16_t keyy_t;\n#endif // WIDE_RANGE\n\n#define KEY(a)      ((uintptr_t)(a) & KEY_MASK)\n\nstruct srlz_data {\n    int val;\n    keyy_t loff, roff;   \n} __attribute__ ((packed));\n\nstruct srlz {\n    size_t sz; // To help on-disk storage/retrieval, etc\n    size_t n;\n    struct srlz_data z[100000];\n} __attribute__ ((packed));\n    \nchar* serialize(struct TreeNode* root) {\n    int of[KEY_MASK] = { 0 }, i = 1, k;\n    struct TreeNode *n[10000] = { root };\n    struct srlz *d = malloc(sizeof *d);\n    struct srlz_data *z = d->z;\n    d->sz = sizeof *d;\n    of[KEY(root)] = i++;        \n    for (int f = 0, b = 1 ; root && f < b ; f++) {\n        z[of[k = KEY(n[f])]].val = n[f]->val;\n        z[of[k]].loff = n[f]->left ? of[KEY(n[b++] = n[f]->left)] = i++ : 0;\n        z[of[k]].roff = n[f]->right ? of[KEY(n[b++] = n[f]->right)] = i++ : 0;\n    }\n    return d->n = root ? i : 0, (char *)d;\n}\n\nstruct TreeNode* deserialize(char* data) {\n    struct srlz *d = (void *)data;\n    struct srlz_data *z = d->z + 1;\n    size_t c = d->n;\n    struct TreeNode *n[100000] = { [1] = c ? malloc(sizeof **n) : NULL };\n    for (int i = 1 ; i < c ; n[i++]->val = z++->val) {\n        n[i]->left = z->loff ? n[z->loff] = malloc(sizeof **n) : NULL;\n        n[i]->right = z->roff ? n[z->roff] = malloc(sizeof **n) : NULL;\n    }\n    return n[1];\n}\n```
['C']