Flatten BST to Sorted List
#include <bits/stdc++.h> // Includes common standard libraries (iostream, vector, etc.)#include "BST.h" // Assumed to contain Node class, insertIntoBST, takeinput, levelOrderTraversal
using namespace std; // Use the standard namespace
// Note: The Node class, insertIntoBST, takeinput, and levelOrderTraversal// are assumed to be defined in "BST.h"./*class Node {public: int data; Node* left; Node* right; Node(int data) { ... }};
Node* insertIntoBST(Node* root, int data) { ... }void takeinput(Node* &root) { ... }void levelOrderTraversal(Node* root) { ... }*/
// Helper function: Performs an in-order traversal of the BST// and stores pointers to all nodes in the 'ans' vector in sorted order.// Time Complexity: O(N)// Space Complexity: O(H) for recursion stackvoid inOrder(Node* root, vector<Node*>& ans) { // Base case: If current node is NULL, return. if(root == NULL) { return; }
// Recursively traverse the left subtree. inOrder(root->left, ans); // After left subtree, add the current node's pointer to the vector. ans.push_back(root); // Recursively traverse the right subtree. inOrder(root->right, ans);}
// Function to flatten a BST into a sorted singly linked list (right-skewed tree).// The 'root' is passed by reference so its pointer can be updated to the new head.// Time Complexity: O(N) (O(N) for in-order + O(N) for relinking)// Space Complexity: O(N) (for storing node pointers in vector)void flattenBST(Node* &root) { // If the tree is empty, nothing to flatten. if(root == NULL) { return; }
// Step 1: Get all node pointers in sorted order using in-order traversal. vector<Node*> arr; inOrder(root, arr); // 'arr' now contains Node* pointers in ascending data order
// Step 2: Relink the nodes to form a right-skewed linked list. // Iterate from the first node up to the second-to-last node. for(int i = 0; i < arr.size() - 1; i++) { arr[i]->left = NULL; // Set left child to NULL for all nodes arr[i]->right = arr[i+1]; // Link current node's right to the next node in sorted order }
// Step 3: Handle the last node in the flattened list (the largest element). arr[arr.size()-1]->left = NULL; // Its left child is NULL arr[arr.size()-1]->right = NULL; // Its right child is NULL (end of the list)
// Step 4: Update the root of the original tree to point to the new head (smallest element). root = arr[0];}
int main() { Node* root = NULL; // Initialize root of the BST
cout << "Enter data to create BST : "; takeinput(root); // Build the BST
cout << endl << "Level Order Traversal (Original BST) : " << endl; levelOrderTraversal(root); // Print the original tree structure
flattenBST(root); // Flatten the BST
// Traverse and print the flattened BST (which is now a linked list via 'right' pointers). Node* temp = root; // Start from the new root (smallest element) cout << endl << "Flattened BST (traverse using right pointers) : "; while(temp != NULL) { cout << temp->data << " "; // Print current node's data temp = temp->right; // Move to the next node using its right pointer } cout << endl; // Newline at the end of output
return 0;}
/*Example Input for tree creation:14 12 28 8 4 10 9 11 19 32 18 17 22 21 24 39 -1
Original Tree Structure (approximate): 14 / \ 12 28 / \ / \ 8 10 19 32 / / \ / \ \ 4 9 11 18 22 39 / \ 17 21 \ 24
In-order sorted sequence of elements:4, 8, 9, 10, 11, 12, 14, 17, 18, 19, 21, 22, 24, 28, 32, 39
Output of Flattened BST:Flattened BST : 4 8 9 10 11 12 14 17 18 19 21 22 24 28 32 39*/1. Binary Search Tree (BST) Recap
- A Binary Search Tree (BST) maintains the property that for any node, values in its left subtree are smaller, and values in its right subtree are greater.
- Crucial Property: An In-order traversal of a BST visits nodes in strictly ascending (sorted) order. This is the foundation of the flattening process.
2. What is “Flattening” a BST?
- Flattening a BST means transforming it into a linear structure, essentially a singly linked list, where all nodes appear in their sorted order.
- In the context of trees, this typically means a right-skewed tree: each node will only have a
rightchild (pointing to the next element in sorted order), and itsleftchild will beNULL.
3. Supporting Components (Briefly)
Nodeclass: Defines the structure of a BST node (data,left,right).insertIntoBST,takeinput,levelOrderTraversal: Functions (assumed inBST.h) to build and visualize the initial BST.
4. inOrder(Node* root, vector<Node*>& ans) Function
- Purpose: This is a helper function that performs an in-order traversal of the BST and collects pointers to all the nodes into a
vector<Node*>. - Logic:
- Base Case: If
rootisNULL, simply return (end of a branch). - Traverse Left: Recursively call
inOrderonroot->left. - Collect Node Pointer: After processing the left subtree, add the
rootpointer itself to theansvector. (This is the “visit” step in in-order traversal). - Traverse Right: Recursively call
inOrderonroot->right.
- Base Case: If
- Result: After this function completes, the
ansvector will containNode*pointers to all nodes in the BST, ordered by their data values (smallest to largest).
5. flattenBST(Node* &root) Function
-
Purpose: To modify the original BST in-place (by manipulating its pointers) so it becomes a sorted singly linked list.
-
Core Idea:
- Get all node pointers in sorted order using the
inOrderhelper. - Iterate through this sorted list of node pointers. For each node, set its
leftchild toNULLand itsrightchild to point to the next node in the sorted sequence. - The original
rootof the BST needs to be updated to point to the first node of this new linear structure (which is the smallest element).
- Get all node pointers in sorted order using the
-
Logic Flow:
- Handle Empty Tree: If the input
rootisNULL, there’s nothing to flatten, so return. - Collect Node Pointers: Create an empty
vector<Node*> arr;and callinOrder(root, arr);. This populatesarrwith node pointers in sorted order. - Relink Nodes:
- Loop from
i = 0up toarr.size() - 2:arr[i]->left = NULL;(Ensure no left child for the flattened list).arr[i]->right = arr[i+1];(Link current node to the next node in the sorted sequence).
- Handle the last node in the
arr(the largest element in the original BST):arr[arr.size()-1]->left = NULL;(No left child).arr[arr.size()-1]->right = NULL;(It’s the end of the linked list).
- Loop from
- Update Tree Root:
root = arr[0];- The original
rootpointer of the BST is updated to point to the first node (smallest element) of the newly formed linked list. Thisrootis passed by reference (Node* &root) to allow this modification.
- The original
- Handle Empty Tree: If the input
6. Complexity Analysis
- Time Complexity:
O(N)O(N)for theinOrdertraversal to collect allNnode pointers.O(N)for the loop that iterates through the vector and relinks allNnodes.- Total:
O(N).
- Space Complexity:
O(N)O(N)for storing allNNode*pointers in thevector<Node*> arr.O(H)for the recursion stack ofinOrdertraversal, whereHis the height of the tree (in worst caseO(N)).- Total: Dominated by the vector storage, so
O(N).