Skip to content
Related Articles

Related Articles

Improve Article
Save Article
Like Article

Flatten a Binary Search Tree to convert the tree into a wave list in place only

  • Difficulty Level : Easy
  • Last Updated : 25 Nov, 2021

Given a Binary Search Tree consisting of N distinct nodes, the task is to flatten the given Binary Search Tree to convert the tree into a wave list. A wave list arr[0..n-1] is called a wave list if arr[0] >= arr[1] <= arr[2] >= arr[3] <= arr[4] >= … .

Examples:

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.  To complete your preparation from learning a language to DS Algo and many more,  please refer Complete Interview Preparation Course.

In case you wish to attend live classes with experts, please refer DSA Live Classes for Working Professionals and Competitive Programming Live for Students.

Input:
                   1
                /     \
             0         10
Output:
              0
                \
                10 
                   \
                    1



Input:      3
              /   \
            1       7
          /   \   /    \
        0     2 5     10
                         
Output:
                      0 
                        \
                         10
                           \
                            1
                             \
                             7
                               \
                                2
                                   \ 
                                    5
                                     \ 
                                     3  

Approach: The given problem can be solved by the observation that the Inorder Traversal of the Binary Search Tree gives nodes in non-decreasing order. Therefore, store the inorder traversal of the given tree of the first N/2 and the last N/2 nodes using the iterative Inorder traversal of the tree and reverse of the inorder traversal of the tree in two stacks S1 and S2 respectively and the right pointer of nodes in the stack to get the Wave List. After these steps, make all the left pointers of the tree NULL to make it flatten.

Below is the implementation of the above approach:

C++




// C++ program for the above approach
 
#include <bits/stdc++.h>
using namespace std;
 
// Tree Node Structure
struct TreeNode {
 
    int data;
    TreeNode* right;
    TreeNode* left;
 
    // Constructor
    TreeNode(int data)
    {
        this->data = data;
        this->left = NULL;
        this->right = NULL;
    }
};
 
// Function to insert nodes in the
// binary tree
TreeNode* insertNode(int data,
                     TreeNode* root)
{
    if (root == NULL) {
        TreeNode* node
            = new TreeNode(data);
        return node;
    }
    else if (data > root->data) {
        root->right = insertNode(
            data, root->right);
    }
    else if (data <= root->data) {
        root->left = insertNode(
            data, root->left);
    }
 
    // Return the root node
    return root;
}
 
// Function to count number of nodes
int countNodes(TreeNode* root)
{
    if (root == NULL)
        return 0;
 
    else
        return countNodes(root->left)
               + countNodes(root->right) + 1;
}
 
// Function to create an array
// to wave array
TreeNode* toWaveList(TreeNode* root)
{
    int count = countNodes(root);
    vector<int> ans;
 
    // For inorder traversal
    stack<TreeNode*> s1;
 
    // For reverse Inorder traversal
    stack<TreeNode*> s2;
 
    TreeNode *root1 = root, *root2 = root;
    TreeNode *curr1 = NULL, *curr2 = NULL;
 
    // To store the root pointer of tree
    // after flattening
    TreeNode* head = NULL;
 
    // Flatten the tree
    TreeNode* temp = NULL;
 
    int l = 0;
    while (l++ < ceil(count / 2.0)) {
 
        // Iterative inorder traversal
        while (root1) {
            s1.push(root1);
            root1 = root1->left;
        }
        curr1 = s1.top();
        s1.pop();
        root1 = curr1->right;
 
        // Iterative reverse inorder
        // traversal
        while (root2) {
            s2.push(root2);
            root2 = root2->right;
        }
        curr2 = s2.top();
        s2.pop();
        root2 = curr2->left;
 
        // Condition for handling situation
        // where both curr1 and curr2 points
        // to the same data
        if (curr1->data == curr2->data) {
            temp->right = curr1;
            temp = temp->right;
            break;
        }
 
        // Flattening the tree
        if (head == NULL) {
            head = curr1;
            temp = curr1;
 
            temp->right = curr2;
 
            // temp->left = NULL
            temp = temp->right;
        }
        else {
 
            temp->right = curr1;
            temp = temp->right;
 
            temp->right = curr2;
            temp = temp->right;
        }
    }
    temp->right = NULL;
 
    // Setting all the left pointers
    // to NULL
    temp = head;
    while (temp) {
        temp->left = NULL;
        temp = temp->right;
    }
 
    return head;
}
 
// Driver Code
int main()
{
    TreeNode* root = NULL;
    int tree[] = { 1, 0, 10 };
    for (int i = 0; i < 3; i++) {
        root = insertNode(tree[i], root);
    }
 
    // Function Call
    TreeNode* head = toWaveList(root);
    while (head) {
        cout << head->data << " ";
        head = head->right;
    }
 
    return 0;
}

Java




// Java program for the above approach
import java.util.*;
class GFG{
 
// Tree Node Structure
static class TreeNode {
 
    int data;
    TreeNode right;
    TreeNode left;
 
    // Constructor
    TreeNode(int data)
    {
        this.data = data;
        this.left = null;
        this.right = null;
    }
};
 
// Function to insert nodes in the
// binary tree
static TreeNode insertNode(int data,
                     TreeNode root)
{
    if (root == null) {
        TreeNode node
            = new TreeNode(data);
        return node;
    }
    else if (data > root.data) {
        root.right = insertNode(
            data, root.right);
    }
    else if (data <= root.data) {
        root.left = insertNode(
            data, root.left);
    }
 
    // Return the root node
    return root;
}
 
// Function to count number of nodes
static int countNodes(TreeNode root)
{
    if (root == null)
    return 0;
 
    else
        return countNodes(root.left)
               + countNodes(root.right) + 1;
}
 
// Function to create an array
// to wave array
static TreeNode toWaveList(TreeNode root)
{
    int count = countNodes(root);
    Vector<Integer> ans = new Vector<>();
 
    // For inorder traversal
    Stack<TreeNode> s1 = new Stack<>();
 
    // For reverse Inorder traversal
    Stack<TreeNode> s2 = new Stack<>();
 
    TreeNode root1 = root, root2 = root;
    TreeNode curr1 = null, curr2 = null;
 
    // To store the root pointer of tree
    // after flattening
    TreeNode head = null;
 
    // Flatten the tree
    TreeNode temp = null;
 
    int l = 0;
    while (l++ < Math.ceil(count / 2.0)) {
 
        // Iterative inorder traversal
        while (root1 != null) {
            s1.add(root1);
            root1 = root1.left;
        }
        curr1 = s1.peek();
        s1.pop();
        root1 = curr1.right;
 
        // Iterative reverse inorder
        // traversal
        while (root2 != null) {
            s2.add(root2);
            root2 = root2.right;
        }
        curr2 = s2.peek();
        s2.pop();
        root2 = curr2.left;
 
        // Condition for handling situation
        // where both curr1 and curr2 points
        // to the same data
        if (curr1.data == curr2.data) {
            temp.right = curr1;
            temp = temp.right;
            break;
        }
 
        // Flattening the tree
        if (head == null) {
            head = curr1;
            temp = curr1;
 
            temp.right = curr2;
 
            // temp.left = null
            temp = temp.right;
        }
        else {
 
            temp.right = curr1;
            temp = temp.right;
 
            temp.right = curr2;
            temp = temp.right;
        }
    }
    temp.right = null;
 
    // Setting all the left pointers
    // to null
    temp = head;
    while (temp!=null) {
        temp.left = null;
        temp = temp.right;
    }
 
    return head;
}
 
// Driver Code
public static void main(String[] args)
{
    TreeNode root = null;
    int tree[] = { 1, 0, 10 };
    for (int i = 0; i < 3; i++) {
        root = insertNode(tree[i], root);
    }
 
    // Function Call
    TreeNode head = toWaveList(root);
    while (head!=null) {
        System.out.print(head.data+ " ");
        head = head.right;
    }
 
}
}
 
// This code is contributed by gauravrajput1

Javascript




<script>
 
// Javascript program for the above approach
 
// Tree Node Structure
class TreeNode {
 
    // Constructor
    constructor(data)
    {
        this.data = data;
        this.left = null;
        this.right = null;
    }
};
 
// Function to insert nodes in the
// binary tree
function insertNode(data, root)
{
    if (root == null) {
        let node = new TreeNode(data);
        return node;
    }
    else if (data > root.data) {
        root.right = insertNode(
            data, root.right);
    }
    else if (data <= root.data) {
        root.left = insertNode(
            data, root.left);
    }
 
    // Return the root node
    return root;
}
 
// Function to count number of nodes
function countNodes(root)
{
    if (root == null)
        return 0;
 
    else
        return countNodes(root.left)
               + countNodes(root.right) + 1;
}
 
// Function to create an array
// to wave array
function toWaveList(root)
{
    let count = countNodes(root);
    let ans = [];
 
    // For inorder traversal
    let s1 = [];
 
    // For reverse Inorder traversal
    let s2 = [];
 
    let root1 = root, root2 = root;
    let curr1 = null, curr2 = null;
 
    // To store the root pointer of tree
    // after flattening
    let head = null;
 
    // Flatten the tree
    let temp = null;
 
    let l = 0;
    while (l++ < Math.ceil(count / 2.0)) {
 
        // Iterative inorder traversal
        while (root1) {
            s1.push(root1);
            root1 = root1.left;
        }
        curr1 = s1[s1.length - 1];
        s1.pop();
        root1 = curr1.right;
 
        // Iterative reverse inorder
        // traversal
        while (root2) {
            s2.push(root2);
            root2 = root2.right;
        }
        curr2 = s2[s2.length - 1]
        s2.pop();
        root2 = curr2.left;
 
        // Condition for handling situation
        // where both curr1 and curr2 points
        // to the same data
        if (curr1.data == curr2.data) {
            temp.right = curr1;
            temp = temp.right;
            break;
        }
 
        // Flattening the tree
        if (head == null) {
            head = curr1;
            temp = curr1;
 
            temp.right = curr2;
 
            // temp.left = null
            temp = temp.right;
        }
        else {
 
            temp.right = curr1;
            temp = temp.right;
 
            temp.right = curr2;
            temp = temp.right;
        }
    }
    temp.right = null;
 
    // Setting all the left pointers
    // to null
    temp = head;
    while (temp) {
        temp.left = null;
        temp = temp.right;
    }
 
    return head;
}
 
// Driver Code
 
    let root = null;
    let tree = [ 1, 0, 10 ];
    for (let i = 0; i < 3; i++) {
        root = insertNode(tree[i], root);
    }
 
    // Function Call
    let head = toWaveList(root);
    while (head) {
        document.write(head.data +" ");
        head = head.right;
    }
 
// This code is contributed by saurabh_jaiswal.
 
</script>

C#




// C# program for the above approach
using System;
using System.Collections.Generic;
 
public class GFG {
 
  // Tree Node Structure
  public    class TreeNode {
 
    public    int data;
    public    TreeNode right;
    public    TreeNode left;
 
    // Constructor
    public    TreeNode(int data) {
      this.data = data;
      this.left = null;
      this.right = null;
    }
  };
 
  // Function to insert nodes in the
  // binary tree
  static TreeNode insertNode(int data, TreeNode root) {
    if (root == null) {
      TreeNode node = new TreeNode(data);
      return node;
    } else if (data > root.data) {
      root.right = insertNode(data, root.right);
    } else if (data <= root.data) {
      root.left = insertNode(data, root.left);
    }
 
    // Return the root node
    return root;
  }
 
  // Function to count number of nodes
  static int countNodes(TreeNode root) {
    if (root == null)
      return 0;
 
    else
      return countNodes(root.left) + countNodes(root.right) + 1;
  }
 
  // Function to create an array
  // to wave array
  static TreeNode toWaveList(TreeNode root) {
    int count = countNodes(root);
    List<int> ans = new List<int>();
 
    // For inorder traversal
    Stack<TreeNode> s1 = new Stack<TreeNode>();
 
    // For reverse Inorder traversal
    Stack<TreeNode> s2 = new Stack<TreeNode>();
 
    TreeNode root1 = root, root2 = root;
    TreeNode curr1 = null, curr2 = null;
 
    // To store the root pointer of tree
    // after flattening
    TreeNode head = null;
 
    // Flatten the tree
    TreeNode temp = null;
 
    int l = 0;
    while (l++ < Math.Ceiling(count / 2.0)) {
 
      // Iterative inorder traversal
      while (root1 != null) {
        s1.Push(root1);
        root1 = root1.left;
      }
      curr1 = s1.Peek();
      s1.Pop();
      root1 = curr1.right;
 
      // Iterative reverse inorder
      // traversal
      while (root2 != null) {
        s2.Push(root2);
        root2 = root2.right;
      }
      curr2 = s2.Peek();
      s2.Pop();
      root2 = curr2.left;
 
      // Condition for handling situation
      // where both curr1 and curr2 points
      // to the same data
      if (curr1.data == curr2.data) {
        temp.right = curr1;
        temp = temp.right;
        break;
      }
 
      // Flattening the tree
      if (head == null) {
        head = curr1;
        temp = curr1;
 
        temp.right = curr2;
 
        // temp.left = null
        temp = temp.right;
      } else {
 
        temp.right = curr1;
        temp = temp.right;
 
        temp.right = curr2;
        temp = temp.right;
      }
    }
    temp.right = null;
 
    // Setting all the left pointers
    // to null
    temp = head;
    while (temp != null) {
      temp.left = null;
      temp = temp.right;
    }
 
    return head;
  }
 
  // Driver Code
  public static void Main(String[] args) {
    TreeNode root = null;
    int []tree = { 1, 0, 10 };
    for (int i = 0; i < 3; i++) {
      root = insertNode(tree[i], root);
    }
 
    // Function Call
    TreeNode head = toWaveList(root);
    while (head != null) {
      Console.Write(head.data + " ");
      head = head.right;
    }
 
  }
}
 
// This code is contributed by gauravrajput1
Output: 
0 10 1

 

Time Complexity: O(N)
Auxiliary Space: O(H), where H is the height of BST.




My Personal Notes arrow_drop_up
Recommended Articles
Page :