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
right
child (pointing to the next element in sorted order), and itsleft
child will beNULL
.
3. Supporting Components (Briefly)
Node
class: 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
root
isNULL
, simply return (end of a branch). - Traverse Left: Recursively call
inOrder
onroot->left
. - Collect Node Pointer: After processing the left subtree, add the
root
pointer itself to theans
vector. (This is the “visit” step in in-order traversal). - Traverse Right: Recursively call
inOrder
onroot->right
.
- Base Case: If
- Result: After this function completes, the
ans
vector 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
inOrder
helper. - Iterate through this sorted list of node pointers. For each node, set its
left
child toNULL
and itsright
child to point to the next node in the sorted sequence. - The original
root
of 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
root
isNULL
, there’s nothing to flatten, so return. - Collect Node Pointers: Create an empty
vector<Node*> arr;
and callinOrder(root, arr);
. This populatesarr
with node pointers in sorted order. - Relink Nodes:
- Loop from
i = 0
up 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
root
pointer of the BST is updated to point to the first node (smallest element) of the newly formed linked list. Thisroot
is 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 theinOrder
traversal to collect allN
node pointers.O(N)
for the loop that iterates through the vector and relinks allN
nodes.- Total:
O(N)
.
- Space Complexity:
O(N)
O(N)
for storing allN
Node*
pointers in thevector<Node*> arr
.O(H)
for the recursion stack ofinOrder
traversal, whereH
is the height of the tree (in worst caseO(N)
).- Total: Dominated by the vector storage, so
O(N)
.