Problem: design an algorithm to save a binary search tree (BST) to a file and restore the original binary search tree from the file. Note the time-space complexity of the algorithm.
Idea: binary tree traversal algorithms include first-order traversal, middle-order traversal, and later-order traversal algorithms. However, there is only one traversal algorithm among them that meets the question conditions and is used to save BST to the file and restore the original BST from the file. Assume that the BST we want to save is as follows:
_ 30_ / \ 20 40 / / \10 35 50
1) sequential Traversal
If we traverse the BST in the middle order, we can get 10 20 30 35 40 50,However, we cannot infer the original binary search tree structure.. The output is 10 20 30 35 40 50. A possible BST structure is shown below. This is an unbalanced BST, which is obviously not the original BST.
_50 / 40 / 35 / 30 / 20 /10
2) Post-order traversal since the Middle-order traversal does not meet the conditions, what about post-order traversal? Post-order traversal prints the leaf node before the parent node is printed. After traversing the BST in the descending order, we can get: 10 20 35 50 40 30. It is difficult to read these nodes and construct the original BST, because when constructing a binary tree, we first construct the parent node and insert the child node, then, the sequential traversal sequence reads the child node first and then the parent node, so it does not meet the condition. 3) The first and second traversal do not meet the conditions. Only the first traversal can meet the conditions. The first traversal result of BST is: 30 20 10 40 35 50. We observe that the parent node of a node is always output before the node. With this observation, after reading the BST node sequence from the file, we can always construct their parent nodes before constructing the child nodes.
The code for writing BST to a file is the same as that for first-order traversal.
Read BST from FileNow the question is, how can we reconstruct the BST from the read node sequence? The simple method is to use the Binary Search Tree insert method to execute n insert operations on each node. Each insert operation takes O (lgn) time, which requires O (nlgn) Time in total.
This method is not efficient enough.
Solution: Review the previous article to determine whether a binary tree is a binary sorting tree. solution 2 uses range determination to determine whether each node meets the conditions. Here we use a similar idea to provide a more efficient solution for re-constructing the original binary search tree from the file. We pass a valid range from the parent node to the child node. When we want to insert a knots, we can determine whether the inserted nodes are in a valid range. If so, We can insert them. Otherwise, we will look for a new location for insertion. The entire time complexity is O (n ).
void readBSTHelper(int min, int max, int &insertVal, struct node *&p, ifstream &fin) { if (insertVal > min && insertVal < max) { int val = insertVal; p = newNode(val); if (fin >> insertVal) { readBSTHelper(min, val, insertVal, p->left, fin); readBSTHelper(val, max, insertVal, p->right, fin); } }} void readBST(struct node *&root, ifstream &fin) { int val; fin >> val; readBSTHelper(INT_MIN, INT_MAX, val, root, fin);}
Original ENGLISH: saving a binary search tree to a file