Python PreOrder + Queue solution with comments
\n# Definition for a binary tree node.\n# class TreeNode(object):\n#     def __init__(self, x):\n#         self.val = x\n#         self.left = None\n#         s
```\n# Definition for a binary tree node.\n# class TreeNode(object):\n#     def __init__(self, x):\n#         self.val = x\n#         self.left = None\n#         self.right = None\n\nclass Codec:\n\n    def serialize(self, root):\n        """Encodes a tree to a single string.\n        \n        :type root: TreeNode\n        :rtype: str\n        """\n        # Pre-Order Traversal of Tree\n        # Putting a marker to notify None/null, so we can recognize it during deserialization\n        if root == None:\n            return \'X,\'\n        \n        left_subtree = self.serialize(root.left) \n        right_subtree = self.serialize(root.right)\n        \n        # Putting a delimiter on which we can split our string on during deserialization\n        return str(root.val) + "," + left_subtree + right_subtree\n    \n    def deserializeHelper(self, data):\n        # If we encounter our marker("X") for None/null node, pop out from our queue(data) and return None\n        # Also its our base condition!!!\n        if data[0] == "X":\n            del data[0]\n            return None\n        \n        # Making a tree node with the front most element in the queue\n        new_node = TreeNode(data[0])\n        del data[0] # Popping our element from queue\n        \n        # When we encounter one "X" we move from left subtree to current(new_node) and when we encounter\n        # two "X"\'s we are moving to the parent (Just trying to explain the recursion taking place)\n        new_node.left = self.deserializeHelper(data) \n        new_node.right = self.deserializeHelper(data)\n        \n        return new_node\n\n    def deserialize(self, data):\n        """Decodes your encoded data to tree.\n        \n        :type data: str\n        :rtype: TreeNode\n        """\n        # Splitting our data on the delimeter we used during serialization\n        data = data.split(",")\n        del data[-1] # Last one will be None/null so omitting it\n        return self.deserializeHelper(data)\n       \n# Thanks to BackToBackSWE (Youtube Channel) for helping me understand this question better\n\n# Your Codec object will be instantiated and called as such:\n# codec = Codec()\n# codec.deserialize(codec.serialize(root))\n```
[]