serialise_deserialise_bt.c (4191B)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 | // 297. Serialize and Deserialize Binary Tree #include "leetcode.h" /* * serialisation is the process of converting a data structure or object into a * sequence of bits so that it can be stored in a file or memory buffer, or * transmitted acorss a network connection link to be reconstructed later in the * same or another computer environment. design an algorithm to serialise and * deserialise a binary tree. there is no restriction on how your serialisation * and deserialisation algorithm shouldd work. you just need to ensure that a * binary tree can be serialised to a string and this string can be deserialised * to the original tree structure. */ struct list { char **data; int pos; int size; }; int comma_cnt(char *s) { int cnt = 0; while (*s != '\0') { cnt += *s == ','; ++s; }; return cnt; } struct list *split(char *s, int size) { struct list *l = (struct list *)malloc(sizeof(struct list)); char **res = (char **)malloc(size * sizeof(char *)), *q = s; for (int i = 0; i < size; ++i) { while (*q != ',' && *q != '\0') ++q; if (*q == ',') { *q = '\0'; ++q; } res[i] = s; s = q; } l->data = res; l->pos = 0; l->size = size; return l; } char *pop(struct list *l) { if (l->pos >= l->size) return NULL; return l->data[l->pos++]; } char *cleanup(char *s) { int i = 0, j = 0; if (s[j] == '[') ++j; while (s[j] != ']' && s[j] != '\0') { if (!isspace(s[j])) s[i++] = s[j]; ++j; } s[i] = '\0'; return s; } /** Encodes a tree to a single string. */ char *serialize(struct TreeNode *root) { if (!root) return NULL; struct TreeNode *queue[21001]; int head = 0, tail = 0; bool has_nodes; struct TreeNode *n; char *s = (char *)malloc(10 * sizeof(char)), num_str[10]; int sl = 1, max_sl = 10; s[0] = '['; queue[tail++] = root; while (head != tail) { n = queue[head++]; if (n) { sprintf(num_str, "%d", n->val); if (sl + strlen(num_str) + 4 >= max_sl) { max_sl *= 2; s = (char *)realloc(s, max_sl); } strcpy(s + sl, num_str); sl += strlen(num_str); s[sl++] = ','; queue[tail++] = n->left; queue[tail++] = n->right; } else { if (sl + 7 > max_sl) { max_sl *= 2; s = (char *)realloc(s, max_sl); } strcpy(s + sl, "null,"); sl += 5; } has_nodes = false; for (int i = head; i < tail; i++) if (queue[i]) { has_nodes = true; break; } if (!has_nodes) head = tail; } s[sl - 1] = ']'; s[sl] = '\0'; return s; } /** Decodes your encoded data to tree. */ struct TreeNode *deserialize(char *data) { if (!data) return NULL; data = cleanup(data); int num_nodes = comma_cnt(data) + 1, head = 0, tail = 0; struct list *l = split(data, num_nodes); struct TreeNode *queue[num_nodes], *root, *n, *m; char *entry = pop(l); if (!entry) return NULL; root = (struct TreeNode *)malloc(sizeof(struct TreeNode)); root->val = atoi(entry); root->left = NULL; root->right = NULL; queue[tail++] = root; while (head != tail) { n = queue[head++]; entry = pop(l); if (entry && strcmp(entry, "null")) { m = (struct TreeNode *)malloc(sizeof(struct TreeNode)); m->val = atoi(entry); m->left = NULL; m->right = NULL; n->left = m; queue[tail++] = m; } entry = pop(l); if (entry && strcmp(entry, "null")) { m = (struct TreeNode *)malloc(sizeof(struct TreeNode)); m->val = atoi(entry); m->left = NULL; m->right = NULL; n->right = m; queue[tail++] = m; } } return root; } // Your functions will be called as such: // char* data = serialize(root); // deserialize(data); int main() { struct TreeNode *root = treenode_create(1); root->left = treenode_create(2); root->right = treenode_create(3); root->right->left = treenode_create(4); root->right->right = treenode_create(5); char *data = serialize(root); struct TreeNode *ds = deserialize(data); treenode_print(ds); // expect: 1 2 3 nll null 4 5 treenode_free(root); treenode_free(ds); free(data); } |