Sunday 24 September 2023

Heap

Insert in Heap,  Delete in Heap, Heapify and HeapSort using max_heap (code in JAVA)


import java.util.ArrayList;

import java.util.Scanner;


public class _heap {

    private static int heapSize;


    public static void main(String[] args) {

        Scanner scanner = new Scanner(System.in);


        System.out.print("Enter the number of elements: ");

        int n = scanner.nextInt();

        ArrayList<Integer> arr = new ArrayList<>();


        System.out.println("Enter the elements:");

        for (int i = 0; i < n; i++) {

            arr.add(scanner.nextInt());

        }


        buildMaxHeap(arr);

        System.out.println("Max Heap after heapify: " + arr);


        while (true) {

            System.out.println("\nChoose operation:");

            System.out.println("1. Insert a node");

            System.out.println("2. Delete maximum element");

            System.out.println("3. HeapSort and Exit");

            int choice = scanner.nextInt();


            if (choice == 1) {

                System.out.print("Enter the element to insert: ");

                int element = scanner.nextInt();

                insert(arr, element);

                System.out.println("Node inserted in heap: " + arr);

            } else if (choice == 2) {

                int max = extractMax(arr);

                System.out.println("Maximum element removed from heap: " + max);

                System.out.println("Heap after deletion: " + arr);

            } else if (choice == 3) {

                heapSort(arr);

                System.out.println("Sorted array: " + arr);

                break;

            } else {

                System.out.println("Invalid choice. Please try again.");

            }

        }


        scanner.close();

    }


    private static void buildMaxHeap(ArrayList<Integer> arr) {

        heapSize = arr.size();

        for (int i = (heapSize / 2) - 1; i >= 0; i--) {

            heapify(arr, i);

        }

    }


    private static void heapify(ArrayList<Integer> arr, int i) {

        heapify(arr, i, heapSize);

    }


    private static void heapify(ArrayList<Integer> arr, int i, int n) {

        int largest = i;

        int left = 2 * i + 1;

        int right = 2 * i + 2;


        if (left < n && arr.get(left) > arr.get(largest)) {

            largest = left;

        }


        if (right < n && arr.get(right) > arr.get(largest)) {

            largest = right;

        }


        if (largest != i) {

            int temp = arr.get(i);

            arr.set(i, arr.get(largest));

            arr.set(largest, temp);

            heapify(arr, largest, n);

        }

    }


    private static void insert(ArrayList<Integer> arr, int element) {

        heapSize++;

        int i = heapSize - 1;

        arr.add(i, element);


        while (i > 0 && arr.get((i - 1) / 2) < arr.get(i)) {

            int parentIndex = (i - 1) / 2;

            int temp = arr.get(i);

            arr.set(i, arr.get(parentIndex));

            arr.set(parentIndex, temp);

            i = parentIndex;

        }

    }


    private static int extractMax(ArrayList<Integer> arr) {

        if (heapSize <= 0) {

            System.out.println("Heap is empty, cannot delete.");

            return -1;

        }


        int root = arr.get(0);

        arr.set(0, arr.remove(heapSize - 1));

        heapSize--;

        heapify(arr, 0);


        return root;

    }


    private static void heapSort(ArrayList<Integer> arr) {

        int n = arr.size();


        // Build a max heap

        buildMaxHeap(arr);


        // Extract elements one by one

        for (int i = n - 1; i >= 0; i--) {

            int temp = arr.get(0);

            arr.set(0, arr.get(i));

            arr.set(i, temp);


            heapify(arr, 0, i);

        }

    }

}


Saturday 23 September 2023

Lowest common ancestor in bst


import java.util.*;

import javax.swing.tree.TreeNode;


public class test {

    static class Node {

        int data;

        Node left;

        Node right;

        int hd;


        public Node(int data) {

            this.data = data;

            this.left = null;

            this.right = null;

            hd = 0;

        }

    }



    static class BinaryTree {

        static Node buildTree(Scanner scanner, String position, int parentValue) {

            System.out.print("Add " + position + " node for " + parentValue + " (y/n): ");

            String userChoice = scanner.next();


            if (userChoice.equalsIgnoreCase("y")) {

                System.out.print("Enter " + position + " node value: ");

                int nodeValue = scanner.nextInt();

                Node newNode = new Node(nodeValue);


                newNode.left = buildTree(scanner, "left", nodeValue);

                newNode.right = buildTree(scanner, "right", nodeValue);


                return newNode;

            } else {

                return null;

            }

        }

    }

    //levelorder traversal

    public static void levelorder(Node root)

    {

        if(root==null) return;

        Queue<Node> q = new LinkedList<>();

        q.add(root);

        q.add(null);

        while(!q.isEmpty())

        {

            Node currnode = q.remove();

            if(currnode==null) //NULL DENOTES NEW LINE

            {

                System.out.println();

                if(q.isEmpty())

                {

                    break;

                }

                else

                {

                    q.add(null);

                }

            }

            else

            {

                System.out.print(currnode.data+" ");

                if(currnode.left!=null)

                {

                    q.add(currnode.left);

                }

                if(currnode.right!=null)

                {

                    q.add(currnode.right);

                }

            }

        }

    }


    public static ArrayList<Integer> preorderUsingStack(Node root)

    {

        ArrayList<Integer> preorderArrayList = new ArrayList<Integer>();

        if (root==null) return preorderArrayList;

        Stack<Node> st = new Stack<Node>();

        st.push(root);

        while(!st.isEmpty())

        {

            root = st.pop();

            preorderArrayList.add(root.data);

            if(root.right != null)

            {

                st.push(root.right);

            }

            if(root.left != null)

            {

                st.push(root.left);

            }


        }

        return preorderArrayList;

    }


    public static ArrayList<Integer> inorderUsingStack(Node root)

    {

        ArrayList<Integer> inorderArrayList = new ArrayList<Integer>();

        if (root == null) return null;

        Stack<Node> st = new Stack<Node>();

        Node node = root;

        while(true)

        {

            if(node != null)

            {

                st.push(node);

                node = node.left;

            }

            else

            {

                if(st.isEmpty())

                {

                    break;

                }

                node = st.pop();

                inorderArrayList.add(node.data);

                node = node.right;

            }

        }

        return inorderArrayList;

    }


    public static ArrayList<Integer> postorderUsing2Stack(Node root)

    {

        ArrayList<Integer> postorderArrayList = new ArrayList<Integer>();

        if(root == null){return postorderArrayList;}

        Stack<Node> st1 = new Stack<Node>();

        Stack<Node> st2 = new Stack<Node>();

        st1.push(root);

        while(!st1.isEmpty())

        {

            root = st1.pop();

            st2.push(root);

            if(root.left!=null) st1.push(root.left);

            if(root.right!=null) st1.push(root.right);

        }

        while(!st2.isEmpty())

        {

            postorderArrayList.add(st2.pop().data);

        }

        return postorderArrayList;

    }


    public static ArrayList<Integer> postorderUsing1Stack(Node root) {

        ArrayList<Integer> postorderArrayList = new ArrayList<Integer>();

        if (root == null) return postorderArrayList;

        Stack<Node> st = new Stack<Node>();

        Node curr = root;

        Node prev = null;

        

        while (curr != null || !st.isEmpty()) {

            if (curr != null) {

                st.push(curr);

                curr = curr.left;

            } else {

                Node peekNode = st.peek();

                if (peekNode.right == null || peekNode.right == prev) { //peekNode is topNode in stack

                    postorderArrayList.add(peekNode.data);

                    prev = peekNode;

                    st.pop();

                } else {

                    curr = peekNode.right;

                }

            }

        }

        

        return postorderArrayList;

    }


    static class node_numOfTraversal_pair

    {

        Node node;

        int num;

        

        public node_numOfTraversal_pair(Node root, int _num)

        {

            this.num = _num;

            this.node = root;

        }

    }


    public static void preInPost_traversal_in_one(Node root, ArrayList<Integer> preorderArrayList, ArrayList<Integer> inorderArrayList, ArrayList<Integer> postorderArrayList)

    {

        Stack<node_numOfTraversal_pair> st = new Stack<node_numOfTraversal_pair>();

        if(root == null) return;

        // or instead of above two lines you can directly write as below

        // node_numOfTraversal_pair pair = new node_numOfTraversal_pair(root,1);

        // st.push(pair);

        st.push(new node_numOfTraversal_pair(root, 1));

        while(!st.isEmpty())

        {

            node_numOfTraversal_pair it = st.pop();

            // this is part of pre

            // increment 1 to 2 

            // push the left side of the tree

            if(it.num == 1)

            {

                preorderArrayList.add(it.node.data);

                it.num++;

                st.push(it);

                if(it.node.left != null)

                {

                    st.push(new node_numOfTraversal_pair(it.node.left, 1));


                }

            }

            // this is a part of in 

            // increment 2 to 3 

            // push right

            else if(it.num == 2)

            {

                inorderArrayList.add(it.node.data);

                it.num++;

                st.push(it);

                if(it.node.right != null)

                {

                    st.push(new node_numOfTraversal_pair(it.node.right, 1));

                }

            }

            // don't push it back again 

            else    

            {

                postorderArrayList.add(it.node.data);

            }

        }


    }


    public static int maxDepthOfBinaryTree(Node root)

    {

        if(root == null) return 0;


        int leftHeight = maxDepthOfBinaryTree(root.left);

        int rightHeight = maxDepthOfBinaryTree(root.right);

        return 1 + Math.max(leftHeight,rightHeight);

    }


    // To check for Balanced Binary Tree

    public static int isBalacedBinaryTree(Node root)

    {

        if(root == null) return 0;


        int leftHeight = isBalacedBinaryTree(root.left);

        if(leftHeight==-1){return -1;}

        int rightHeight = isBalacedBinaryTree(root.right);

        if(rightHeight==-1){return -1;}

        if(Math.abs(leftHeight-rightHeight)>1){return -1;}

        return 1 + Math.max(leftHeight,rightHeight);

    }

    public static boolean isBalancedBinaryTree_boolean_value(Node root)

    {

        return isBalacedBinaryTree(root) != -1;

    }


    // To measure diameter of binary tree

    public static int height(Node root, int diameter[])

    {

        if(root == null) return 0;


        int leftHeight = height(root.left,diameter);

        int rightHeight = height(root.right,diameter);

        diameter[0] = Math.max(diameter[0],leftHeight+rightHeight);

        return 1 + Math.max(leftHeight,rightHeight);

    }

    public static int diameterofbinarytree(Node root)

    {

        int diameter1[]= new int[1];

        height(root,diameter1);

        return diameter1[0];

    }


    // Maximum Path Sum

    public static int maxPath(Node node, int maxValue[]) {

        if (node == null) return 0;

        int left = Math.max(0, maxPath(node.left, maxValue));

        int right = Math.max(0, maxPath(node.right, maxValue));

        maxValue[0] = Math.max(maxValue[0], left + right + node.data);

        return Math.max(left, right) + node.data;

    }

    public static int maxPathSum(Node root) {

        int maxValue[] = new int[1];

        maxValue[0] = Integer.MIN_VALUE;

        maxPath(root, maxValue);

        return maxValue[0];

    }


    // Zig-zag or spiral traversal 

    static ArrayList<Integer> zigZagTraversal(Node root)

    {

        ArrayList<Integer> ans = new ArrayList<Integer>();

        if (root == null)

            return ans;

        Queue<Node> q = new LinkedList<Node>();

        q.add(root);

        boolean leftToRight = true;

        while (q.size() > 0) {

            int size = q.size();

            ArrayList<Integer> temp = new ArrayList<>();

            for (int i = 0; i < size; i++) {

                Node curr = q.poll();

                if (curr.left != null)

                    q.add(curr.left);

                if (curr.right != null)

                    q.add(curr.right);

                temp.add(curr.data);

            }

            if (leftToRight) 

            {

                // do nothing

            }

            else {

                Collections.reverse(temp);

            }

            for (int i = 0; i < temp.size(); i++) {

                ans.add(temp.get(i));

            }

            leftToRight = !(leftToRight);

        }

        return ans;

    }


    // boundary traversal

     public static void printLeftBoundary(Node node) {

        if (node == null)

            return;

        if (node.left != null) {

            System.out.print(node.data + " ");

            printLeftBoundary(node.left);

        } else if (node.right != null) {

            System.out.print(node.data + " ");

            printLeftBoundary(node.right);

        }

    }


    public static void printRightBoundary(Node node) {

        if (node == null)

            return;

        if (node.right != null) {

            printRightBoundary(node.right);

            System.out.print(node.data + " ");

        } else if (node.left != null) {

            printRightBoundary(node.left);

            System.out.print(node.data + " ");

        }

    }


    public static void printLeaves(Node node) {

        if (node == null)

            return;


        printLeaves(node.left);

        if (node.left == null && node.right == null)

            System.out.print(node.data + " ");

        printLeaves(node.right);

    }


    public static void boundaryTraversal(Node root) {

        if (root == null)

            return;

        System.out.print(root.data + " ");

        printLeftBoundary(root.left);

        printLeaves(root.left);

        printLeaves(root.right);

        printRightBoundary(root.right);

    }


    // Vertical order traversal

    public static void verticalOrder(Node root,int horizontal_dist, Map<Integer, Vector<Integer>> m)

    {

        if (root==null) return;

        Vector<Integer> v = m.get(horizontal_dist);

        if(v==null)

        {

            v = new Vector<Integer>();

            v.add(root.data);

        }

        else

        {

            v.add(root.data);

        }

        m.put(horizontal_dist,v);

        verticalOrder(root.left, horizontal_dist - 1, m);

        verticalOrder(root.right, horizontal_dist + 1, m);

    }


    // Top-view of a binary tree

    public static class Pair {

        Node node;

        int hd;

    

        Pair(Node node, int hd) {

            this.node = node;

            this.hd = hd;

        }

    }

    

    static ArrayList<Integer> topView(Node root)

    {

        ArrayList<Integer> ans = new ArrayList<>(); 

        if(root == null) return ans;

        Map<Integer, Integer> map = new TreeMap<>();

        Queue<Pair> q = new LinkedList<Pair>();

        q.add(new Pair(root, 0)); 

        while(!q.isEmpty()) {

            Pair it = q.remove();

            int hd = it.hd; 

            Node temp = it.node; 

            if(map.get(hd) == null) map.put(hd, temp.data); 

            if(temp.left != null) {

                

                q.add(new Pair(temp.left, hd - 1)); 

            }

            if(temp.right != null) {

                

                q.add(new Pair(temp.right, hd + 1)); 

            }

        }

    

        for (Map.Entry<Integer,Integer> entry : map.entrySet()) {

            ans.add(entry.getValue()); 

        }

        return ans; 

    }


    // Bottom-View of Binary Tree

   

    public static ArrayList <Integer> bottomView(Node root)

    {

        ArrayList<Integer> ans = new ArrayList<>(); 

        if(root == null) return ans;

        Map<Integer, Integer> map = new TreeMap<>();

        Queue<Node> q = new LinkedList<Node>();

        root.hd = 0;

        q.add(root); 

        while(!q.isEmpty()) {

            Node temp = q.remove();

            int hd = temp.hd; 

            map.put(hd, temp.data); 

            if(temp.left != null) {

                temp.left.hd = hd - 1; 

                q.add(temp.left); 

            }

            if(temp.right != null) {

                temp.right.hd = hd + 1; 

                q.add(temp.right); 

            }

        }

        

        for (Map.Entry<Integer,Integer> entry : map.entrySet()) {

            ans.add(entry.getValue()); 

        }

        return ans; 

    }


    // Right View of binary tree

    public static List<Integer> rightSideView(Node root) {

        List<Integer> result = new ArrayList<Integer>();

        rightView(root, result, 0);

        return result;

    }

    

    public static void rightView(Node curr, List<Integer> result, int currDepth){

        if(curr == null){

            return;

        }

        if(currDepth == result.size()){

            result.add(curr.data);

        }

        

        rightView(curr.right, result, currDepth + 1);

        rightView(curr.left, result, currDepth + 1);

        

    }

    //Left-side view

    public static List<Integer> leftSideView(Node root) {

        List<Integer> result = new ArrayList<Integer>();

        leftView(root, result, 0);

        return result;

    }

    

    public static void leftView(Node curr, List<Integer> result, int currDepth){

        if(curr == null){

            return;

        }

        if(currDepth == result.size()){

            result.add(curr.data);

        }

        

        leftView(curr.left, result, currDepth + 1);

        leftView(curr.right, result, currDepth + 1);

    }


    // Check if bianry tree is symmetric or not

    static boolean isSymmetricUtil(Node  root1, Node  root2) {

        if (root1 == null || root2 == null)

          return root1 == root2;

        return (root1 . data == root2 . data) && isSymmetricUtil(root1 . left, root2 . 

        right) && isSymmetricUtil(root1 . right, root2 . left);

      }

      static boolean isSymmetric(Node  root) {

        if (root==null) return true;

        return isSymmetricUtil(root . left, root . right);

      }

      

      // Print root to node path

      static boolean getPath(Node root, ArrayList < Integer > arr, int x) {

         

        if (root == null)

            return false;

        arr.add(root.data);

        if (root.data == x)

            return true;

        if (getPath(root.left, arr, x) ||

            getPath(root.right, arr, x))

            return true;

        arr.remove(arr.size() - 1);

        return false;

    }


    public static void  printPath(Node root, int node_data)

    {

        ArrayList < Integer > arr = new ArrayList < > ();

        boolean res;

        res = getPath(root, arr, node_data);


        System.out.print("The Root to node path is: ");

        for (int it: arr) {

            System.out.print(it + " ");

        }

    }


    // lowest common ancestor of binary tree

     public static Node lowestCommonAncestor(Node root, Node p, Node q) {

        if (root == null || root == p || root == q) {

            return root;

        }

        Node left = lowestCommonAncestor(root.left, p, q);

        Node right = lowestCommonAncestor(root.right, p, q);


        //result

        if(left == null) {

            return right;

        }

        else if(right == null) {

            return left;

        }

        else { //both left and right are not null, we found our result

            return root;

        }

    }


    // Maximum width of a binary tree

    public static int widthOfBinaryTree(Node root) {

        if(root == null) return 0;

        int ans = 0;

        Queue<Pair> q = new LinkedList<>(); 

        q.offer(new Pair(root, 0)); 

        while(!q.isEmpty()){

            int size = q.size();

            int mmin = q.peek().hd;    //to make the id starting from zero  

            int first = 0,last = 0;   //hd code written in Pair class

            for(int i=0; i<size; i++){

                int cur_id = q.peek().hd-mmin;

                Node node = q.peek().node;

                q.poll();

                if(i==0) first = cur_id;

                if(i==size-1) last = cur_id;

                if(node.left != null)

                    q.offer(new Pair(node.left, cur_id*2+1));

                if(node.right != null) 

                    q.offer(new Pair(node.right, cur_id*2+2));

            }

            ans = Math.max(ans, last-first+1);

        }

        return ans;

    }


    //Children sum property in binary tree

    static void reorder(Node  root) {

        if (root == null) return;

        int child = 0;

        if (root . left!=null) {

          child += root . left . data;

        }

        if (root . right!=null) {

          child += root . right . data;

        }

      

        if (child < root . data) {

          if (root . left!=null) root . left . data = root . data;

          else if (root . right!=null) root . right . data = root . data;

        }

      

        reorder(root . left);

        reorder(root . right);

      

        int tot = 0;

        if (root . left!=null) tot += root . left . data;

        if (root . right!=null) tot += root . right . data;

        if (root . left!=null || root . right!=null) root . data = tot;

      }

      static void changeTree(Node  root) {

        reorder(root);

      }


      //print nodes at distance k

      static void printkdistanceNodeDown(Node node, int k)

      {

          // Base Case

          if (node == null || k < 0)

              return;

    

          // If we reach a k distant node, print it

          if (k == 0)

          {

              System.out.print(node.data);

              System.out.println("");

              return;

          }

    

          // Recur for left and right subtrees

          printkdistanceNodeDown(node.left, k - 1);

          printkdistanceNodeDown(node.right, k - 1);

      }

    

      // Prints all nodes at distance k from a given target node.

      // The k distant nodes may be upward or downward.This function

      // Returns distance of root from target node, it returns -1

      // if target node is not present in tree rooted with root.

      static int printkdistanceNode(Node node, Node target, int k)

      {

          // Base Case 1: If tree is empty, return -1

          if (node == null)

              return -1;

    

          // If target is same as root.  Use the downward function

          // to print all nodes at distance k in subtree rooted with

          // target or root

          if (node == target)

          {

              printkdistanceNodeDown(node, k);

              return 0;

          }

    

          // Recur for left subtree

          int dl = printkdistanceNode(node.left, target, k);

    

          // Check if target node was found in left subtree

          if (dl != -1)

          {

                

              // If root is at distance k from target, print root

              // Note that dl is Distance of root's left child from

              // target

              if (dl + 1 == k)

              {

                  System.out.print(node.data);

                  System.out.println("");

              }

                

              // Else go to right subtree and print all k-dl-2 distant nodes

              // Note that the right child is 2 edges away from left child

              else

                  printkdistanceNodeDown(node.right, k - dl - 2);

    

              // Add 1 to the distance and return value for parent calls

              return 1 + dl;

          }

    

          // MIRROR OF ABOVE CODE FOR RIGHT SUBTREE

          // Note that we reach here only when node was not found in left

          // subtree

          int dr = printkdistanceNode(node.right, target, k);

          if (dr != -1)

          {

              if (dr + 1 == k)

              {

                  System.out.print(node.data);

                  System.out.println("");

              }

              else

                  printkdistanceNodeDown(node.left, k - dr - 2);

              return 1 + dr;

          }

    

          // If target was neither present in left nor in right subtree

          return -1;

      }

      

      //count total number of nodes in complete binary tree

      static void inOrderTrav(Node  curr, int count[]) {

        if (curr == null)

          return;

      

        count[0]++;

        inOrderTrav(curr . left, count);

        inOrderTrav(curr . right, count);

      }


      // Serialise and De-Serialise

      public static String serialize(Node root) {

        if (root == null) return "";

        Queue<Node> q = new LinkedList<>();

        StringBuilder res = new StringBuilder();

        q.add(root);

        while (!q.isEmpty()) {

            Node node = q.poll();

            if (node == null) {

                res.append("n ");

                continue;

            }

            res.append(node.data + " ");

            q.add(node.left);

            q.add(node.right);

        }

        return res.toString();

    }


    public static Node deserialize(String data) {

        if (data == "") return null;

        Queue<Node> q = new LinkedList<>();

        String[] values = data.split(" ");

        Node root = new Node(Integer.parseInt(values[0]));

        q.add(root);

        for (int i = 1; i < values.length; i++) {

            Node parent = q.poll();

            if (!values[i].equals("n")) {

                Node left = new Node(Integer.parseInt(values[i]));

                parent.left = left;

                q.add(left);

            }

            if (!values[++i].equals("n")) {

                Node right = new Node(Integer.parseInt(values[i]));

                parent.right = right;

                q.add(right);

            }

        }

        return root;

    }


    //Morris inorder traversal of a binary tree

    public static List<Integer> MorrisInorderTraversal(Node root) {

        List<Integer> inorder = new ArrayList<Integer>(); 

        

        Node cur = root; 

        while(cur != null) {

            if(cur.left == null) {

                inorder.add(cur.data); 

                cur = cur.right; 

            }

            else {

                Node prev = cur.left; 

                while(prev.right != null && prev.right != cur) {

                    prev = prev.right; 

                }

                

                if(prev.right == null) {

                    prev.right = cur;

                    cur = cur.left; 

                }

                else {

                    prev.right = null; 

                    inorder.add(cur.data); 

                    cur = cur.right; 

                }

            }

        }

        return inorder; 

    }


    //Morris preorder traversal of a binary tree

    public static ArrayList < Integer > MorrisPreorderTraversal(Node root) {

        ArrayList < Integer > preorder = new ArrayList < > ();

        Node cur = root;

        while (cur != null) {

            if (cur.left == null) {

                preorder.add(cur.data);

                cur = cur.right;

            } else {

                Node prev = cur.left;

                while (prev.right != null && prev.right != cur) {

                    prev = prev.right;

                }


                if (prev.right == null) {

                    prev.right = cur;

                    preorder.add(cur.data);

                    cur = cur.left;

                } else {

                    prev.right = null;

                    cur = cur.right;

                }

            }

        }

        return preorder;

    }


    //Flatten Binary Tree to Linked List 

    //  using recursion


    static Node prev = null;

    static void flatten(Node  root) {

      if (root == null) return;


      flatten(root . right);

      flatten(root . left);


      root . right = prev;

      root . left = null;

      prev = root;

    }


    public static void BinaryToLinkedList_recursion(Node root)

    {

        flatten(root);

        while(root.right!=null)

    {

      System.out.print(root.data+"->");

      root=root.right;

    }

    System.out.print(root.data);

    }

    //using stack and using morris traversal are also there the code is commented

    /*

     using stack

     static Node prev = null;

    static void flatten(Node  root) {

  if (root == null) return;

  Stack < Node  > st=new Stack<>();

  st.push(root);

  while (!st.isEmpty()) {

    Node  cur = st.peek();

    st.pop();


    if (cur . right != null) {

      st.push(cur . right);

    }

    if (cur . left != null) {

      st.push(cur . left);

    }

    if (!st.isEmpty()) {

      cur . right = st.peek();

    }

    cur . left = null;

  }


}


// using morris travesal

    static Node prev = null;

    static void flatten(Node root) {

        Node cur = root;

while (cur!=null)

{

if(cur.left!=null)

{

Node pre = cur.left;

while(pre.right!=null)

{

pre = pre.right;

}

pre.right = cur.right;

cur.right = cur.left;

cur.left = null;

}

cur = cur.right;

}

    }


     */


    // Binary Search Tree (BST)

    // SEARCH IN BST

    public static Node searchBST(Node root, int val) {

        if (root == null || root.data == val) {

            return root;

        }


        if (val < root.data) {

            return searchBST(root.left, val);

        }


        return searchBST(root.right, val);

    }


    public static void printsearchBST(Node root,int target)

    {

        root = searchBST(root, target);

        if (root != null) {

            System.out.println(target + " found in the BST.");

        } else {

            System.out.println(target + " not found in the BST.");

        }

    }


    // CEIL IN BST

    public static int findCeil(Node root,int key)

    {

        int ceil = -1;

        while(root!=null)

        {

            if(root.data==key)

            {

                ceil = root.data;

                return ceil;

            }

            if(key>root.data)

            {

                root=root.right;

            }

            else

            {

                ceil=root.data;

                root=root.left;

            }

        }

        return ceil;

    }


    // Insert node in BST

    public static Node insertIntoBST(Node root,int val)

    {

        if(root==null) return new Node(val);

        Node cur = root;

        while(true)

        {

            if(cur.data<=val)

            {

                if(cur.right!=null) cur=cur.right;

                else{

                    cur.right=new Node(val);

                    break;

                }

            }

            else{

                

                if(cur.left!=null) cur=cur.left;

                else{

                    cur.left=new Node(val);

                    break;

                }

            }

        }

        return root;

    }


    // Deletion in BST

     // Get minimum element in binary search tree

     public static Node minimumElement(Node root) {

        if (root.left == null)

            return root;

        else {

            return minimumElement(root.left);

        }

    }

 

    public static Node deleteNode(Node root, int value) {

        if (root == null)

            return null;

        if (root.data > value) {

            root.left = deleteNode(root.left, value);

        } else if (root.data < value) {

            root.right = deleteNode(root.right, value);

 

        } else {

            // if nodeToBeDeleted have both children

            if (root.left != null && root.right != null) {

                Node temp = root;

                // Finding minimum element from right

                Node minNodeForRight = minimumElement(temp.right);

                // Replacing current node with minimum node from right subtree

                root.data = minNodeForRight.data;

                // Deleting minimum node from right now

                root.right = deleteNode(root.right, minNodeForRight.data);

 

            }

            // if nodeToBeDeleted has only left child

            else if (root.left != null) {

                root = root.left;

            }

            // if nodeToBeDeleted has only right child

            else if (root.right != null) {

                root = root.right;

            }

            // if nodeToBeDeleted do not have child (Leaf node)

            else

                root = null;

        }

        return root;

    }

   

    // Find lca in bst

    public static Node lca(Node root, Node p, Node q)

    {

        if(root == null) return null;

        int curr = root.data;

        if(curr < p.data && curr < q.data)

        {

             return lca(root.right, p , q);

        }

        if(curr > p.data && curr > q.data)

        {

            return lca(root.left, p , q);

        }

        return root;

    }

    

    public static void main(String[] args) {

        Scanner scanner = new Scanner(System.in);

        BinaryTree bt = new BinaryTree();

        

        System.out.print("Enter root node value: ");

        int rootValue = scanner.nextInt();

        Node root = new Node(rootValue);


        root.left = bt.buildTree(scanner, "left", rootValue);

        root.right = bt.buildTree(scanner, "right", rootValue);


        System.out.println("Tree construction complete.");

        levelorder(root);

        System.out.println(preorderUsingStack(root));

        System.out.println(inorderUsingStack(root));

        System.out.println(postorderUsing2Stack(root));

        System.out.println(postorderUsing1Stack(root));

        ArrayList<Integer> preorderArrayList = new ArrayList<Integer>();

        ArrayList<Integer> inorderArrayList = new ArrayList<Integer>();

        ArrayList<Integer> postorderArrayList = new ArrayList<Integer>();

        preInPost_traversal_in_one(root, preorderArrayList, inorderArrayList, postorderArrayList);

        System.out.print("The preorder traversal is: ");

        for (Integer pre : preorderArrayList) {

            System.out.print(pre+" ");

        }

        System.out.println();

        System.out.print("The inorder traversal is: ");

        for (Integer in : inorderArrayList) {

            System.out.print(in+" ");

        }

        System.out.println();

        System.out.print("The postorder traversal is: ");

        for (Integer post : postorderArrayList) {

            System.out.print(post+" ");

        }

        System.out.println();

        System.out.println("The depth of your tree is: "+maxDepthOfBinaryTree(root));

        boolean balanced_var = isBalancedBinaryTree_boolean_value(root);

        System.out.println(balanced_var);

        System.out.println("The diameter of given binary tree is: "+diameterofbinarytree(root));

        System.out.println("The maximum path sum is: "+maxPathSum(root));

        System.out.println("The zigZag Traversal is: "+zigZagTraversal(root));

        System.out.println("The boundary traversal is as below:");

        boundaryTraversal(root);

        System.out.println();

        System.out.println("The vertical order traversal is as below:");

        TreeMap<Integer, Vector<Integer>> m = new TreeMap<>();

        int hd = 0;

        verticalOrder(root, hd, m);

        for (Map.Entry<Integer,Vector<Integer>> e : m.entrySet()) {

            System.out.println(e.getValue());

        }

        System.out.println("Top view traversal is :");

        System.out.println(topView(root));

        System.out.println("Bottom view traversal is :");

        System.out.println(bottomView(root));

        System.out.println("The right-side view is:");

        System.out.println(rightSideView(root));

        System.out.println("The left-side view is:");

        System.out.println(leftSideView(root));

        System.out.println("The binary tree is symmetric: "+isSymmetric(root));

        printPath(root, 7);

        System.out.println();

        //System.out.println("The lowest common ancestor is: "+lowestCommonAncestor(root, root.left.left, root.left.right.right).data);

        System.out.println("The maximum width of a binary tree is: "+widthOfBinaryTree(root));

        //System.out.println("Level order traversal of tree after children sum property is: ");

        //changeTree(root);

        //levelorder(root);

        //System.out.println("The nodes at distance k is: ");

        //Node target = root.left.right;

        //printkdistanceNode(root, target, 2);

        //System.out.println("--");

        int count[]=new int[1];

        inOrderTrav(root, count);

        System.out.println("The total number of nodes in the given complete binary tree are: "+count[0]);

        System.out.println(serialize(root));

        System.out.println(deserialize(serialize(root)).data);

        System.out.println(MorrisInorderTraversal(root));

        System.out.println(MorrisPreorderTraversal(root));

        //BinaryToLinkedList_recursion(root);

        printsearchBST(root, 8);

        System.out.println(findCeil(root, 4));

        //insertIntoBST(root, 0);

        System.out.println("--");

        deleteNode(root, 50);

        levelorder(root);

        Node p1 = new Node(5);

        Node q1 = new Node(13);

        System.out.println("The lowest common ancestor is: "+lca(root,p1,q1).data);

        scanner.close();

    }

}



  

Insert  a given node Into BST (code in JAVA)


import java.util.*;

import javax.swing.tree.TreeNode;


public class test {

    static class Node {

        int data;

        Node left;

        Node right;

        int hd;


        public Node(int data) {

            this.data = data;

            this.left = null;

            this.right = null;

            hd = 0;

        }

    }



    static class BinaryTree {

        static Node buildTree(Scanner scanner, String position, int parentValue) {

            System.out.print("Add " + position + " node for " + parentValue + " (y/n): ");

            String userChoice = scanner.next();


            if (userChoice.equalsIgnoreCase("y")) {

                System.out.print("Enter " + position + " node value: ");

                int nodeValue = scanner.nextInt();

                Node newNode = new Node(nodeValue);


                newNode.left = buildTree(scanner, "left", nodeValue);

                newNode.right = buildTree(scanner, "right", nodeValue);


                return newNode;

            } else {

                return null;

            }

        }

    }

    //levelorder traversal

    public static void levelorder(Node root)

    {

        if(root==null) return;

        Queue<Node> q = new LinkedList<>();

        q.add(root);

        q.add(null);

        while(!q.isEmpty())

        {

            Node currnode = q.remove();

            if(currnode==null) //NULL DENOTES NEW LINE

            {

                System.out.println();

                if(q.isEmpty())

                {

                    break;

                }

                else

                {

                    q.add(null);

                }

            }

            else

            {

                System.out.print(currnode.data+" ");

                if(currnode.left!=null)

                {

                    q.add(currnode.left);

                }

                if(currnode.right!=null)

                {

                    q.add(currnode.right);

                }

            }

        }

    }


    public static ArrayList<Integer> preorderUsingStack(Node root)

    {

        ArrayList<Integer> preorderArrayList = new ArrayList<Integer>();

        if (root==null) return preorderArrayList;

        Stack<Node> st = new Stack<Node>();

        st.push(root);

        while(!st.isEmpty())

        {

            root = st.pop();

            preorderArrayList.add(root.data);

            if(root.right != null)

            {

                st.push(root.right);

            }

            if(root.left != null)

            {

                st.push(root.left);

            }


        }

        return preorderArrayList;

    }


    public static ArrayList<Integer> inorderUsingStack(Node root)

    {

        ArrayList<Integer> inorderArrayList = new ArrayList<Integer>();

        if (root == null) return null;

        Stack<Node> st = new Stack<Node>();

        Node node = root;

        while(true)

        {

            if(node != null)

            {

                st.push(node);

                node = node.left;

            }

            else

            {

                if(st.isEmpty())

                {

                    break;

                }

                node = st.pop();

                inorderArrayList.add(node.data);

                node = node.right;

            }

        }

        return inorderArrayList;

    }


    public static ArrayList<Integer> postorderUsing2Stack(Node root)

    {

        ArrayList<Integer> postorderArrayList = new ArrayList<Integer>();

        if(root == null){return postorderArrayList;}

        Stack<Node> st1 = new Stack<Node>();

        Stack<Node> st2 = new Stack<Node>();

        st1.push(root);

        while(!st1.isEmpty())

        {

            root = st1.pop();

            st2.push(root);

            if(root.left!=null) st1.push(root.left);

            if(root.right!=null) st1.push(root.right);

        }

        while(!st2.isEmpty())

        {

            postorderArrayList.add(st2.pop().data);

        }

        return postorderArrayList;

    }


    public static ArrayList<Integer> postorderUsing1Stack(Node root) {

        ArrayList<Integer> postorderArrayList = new ArrayList<Integer>();

        if (root == null) return postorderArrayList;

        Stack<Node> st = new Stack<Node>();

        Node curr = root;

        Node prev = null;

        

        while (curr != null || !st.isEmpty()) {

            if (curr != null) {

                st.push(curr);

                curr = curr.left;

            } else {

                Node peekNode = st.peek();

                if (peekNode.right == null || peekNode.right == prev) { //peekNode is topNode in stack

                    postorderArrayList.add(peekNode.data);

                    prev = peekNode;

                    st.pop();

                } else {

                    curr = peekNode.right;

                }

            }

        }

        

        return postorderArrayList;

    }


    static class node_numOfTraversal_pair

    {

        Node node;

        int num;

        

        public node_numOfTraversal_pair(Node root, int _num)

        {

            this.num = _num;

            this.node = root;

        }

    }


    public static void preInPost_traversal_in_one(Node root, ArrayList<Integer> preorderArrayList, ArrayList<Integer> inorderArrayList, ArrayList<Integer> postorderArrayList)

    {

        Stack<node_numOfTraversal_pair> st = new Stack<node_numOfTraversal_pair>();

        if(root == null) return;

        // or instead of above two lines you can directly write as below

        // node_numOfTraversal_pair pair = new node_numOfTraversal_pair(root,1);

        // st.push(pair);

        st.push(new node_numOfTraversal_pair(root, 1));

        while(!st.isEmpty())

        {

            node_numOfTraversal_pair it = st.pop();

            // this is part of pre

            // increment 1 to 2 

            // push the left side of the tree

            if(it.num == 1)

            {

                preorderArrayList.add(it.node.data);

                it.num++;

                st.push(it);

                if(it.node.left != null)

                {

                    st.push(new node_numOfTraversal_pair(it.node.left, 1));


                }

            }

            // this is a part of in 

            // increment 2 to 3 

            // push right

            else if(it.num == 2)

            {

                inorderArrayList.add(it.node.data);

                it.num++;

                st.push(it);

                if(it.node.right != null)

                {

                    st.push(new node_numOfTraversal_pair(it.node.right, 1));

                }

            }

            // don't push it back again 

            else    

            {

                postorderArrayList.add(it.node.data);

            }

        }


    }


    public static int maxDepthOfBinaryTree(Node root)

    {

        if(root == null) return 0;


        int leftHeight = maxDepthOfBinaryTree(root.left);

        int rightHeight = maxDepthOfBinaryTree(root.right);

        return 1 + Math.max(leftHeight,rightHeight);

    }


    // To check for Balanced Binary Tree

    public static int isBalacedBinaryTree(Node root)

    {

        if(root == null) return 0;


        int leftHeight = isBalacedBinaryTree(root.left);

        if(leftHeight==-1){return -1;}

        int rightHeight = isBalacedBinaryTree(root.right);

        if(rightHeight==-1){return -1;}

        if(Math.abs(leftHeight-rightHeight)>1){return -1;}

        return 1 + Math.max(leftHeight,rightHeight);

    }

    public static boolean isBalancedBinaryTree_boolean_value(Node root)

    {

        return isBalacedBinaryTree(root) != -1;

    }


    // To measure diameter of binary tree

    public static int height(Node root, int diameter[])

    {

        if(root == null) return 0;


        int leftHeight = height(root.left,diameter);

        int rightHeight = height(root.right,diameter);

        diameter[0] = Math.max(diameter[0],leftHeight+rightHeight);

        return 1 + Math.max(leftHeight,rightHeight);

    }

    public static int diameterofbinarytree(Node root)

    {

        int diameter1[]= new int[1];

        height(root,diameter1);

        return diameter1[0];

    }


    // Maximum Path Sum

    public static int maxPath(Node node, int maxValue[]) {

        if (node == null) return 0;

        int left = Math.max(0, maxPath(node.left, maxValue));

        int right = Math.max(0, maxPath(node.right, maxValue));

        maxValue[0] = Math.max(maxValue[0], left + right + node.data);

        return Math.max(left, right) + node.data;

    }

    public static int maxPathSum(Node root) {

        int maxValue[] = new int[1];

        maxValue[0] = Integer.MIN_VALUE;

        maxPath(root, maxValue);

        return maxValue[0];

    }


    // Zig-zag or spiral traversal 

    static ArrayList<Integer> zigZagTraversal(Node root)

    {

        ArrayList<Integer> ans = new ArrayList<Integer>();

        if (root == null)

            return ans;

        Queue<Node> q = new LinkedList<Node>();

        q.add(root);

        boolean leftToRight = true;

        while (q.size() > 0) {

            int size = q.size();

            ArrayList<Integer> temp = new ArrayList<>();

            for (int i = 0; i < size; i++) {

                Node curr = q.poll();

                if (curr.left != null)

                    q.add(curr.left);

                if (curr.right != null)

                    q.add(curr.right);

                temp.add(curr.data);

            }

            if (leftToRight) 

            {

                // do nothing

            }

            else {

                Collections.reverse(temp);

            }

            for (int i = 0; i < temp.size(); i++) {

                ans.add(temp.get(i));

            }

            leftToRight = !(leftToRight);

        }

        return ans;

    }


    // boundary traversal

     public static void printLeftBoundary(Node node) {

        if (node == null)

            return;

        if (node.left != null) {

            System.out.print(node.data + " ");

            printLeftBoundary(node.left);

        } else if (node.right != null) {

            System.out.print(node.data + " ");

            printLeftBoundary(node.right);

        }

    }


    public static void printRightBoundary(Node node) {

        if (node == null)

            return;

        if (node.right != null) {

            printRightBoundary(node.right);

            System.out.print(node.data + " ");

        } else if (node.left != null) {

            printRightBoundary(node.left);

            System.out.print(node.data + " ");

        }

    }


    public static void printLeaves(Node node) {

        if (node == null)

            return;


        printLeaves(node.left);

        if (node.left == null && node.right == null)

            System.out.print(node.data + " ");

        printLeaves(node.right);

    }


    public static void boundaryTraversal(Node root) {

        if (root == null)

            return;

        System.out.print(root.data + " ");

        printLeftBoundary(root.left);

        printLeaves(root.left);

        printLeaves(root.right);

        printRightBoundary(root.right);

    }


    // Vertical order traversal

    public static void verticalOrder(Node root,int horizontal_dist, Map<Integer, Vector<Integer>> m)

    {

        if (root==null) return;

        Vector<Integer> v = m.get(horizontal_dist);

        if(v==null)

        {

            v = new Vector<Integer>();

            v.add(root.data);

        }

        else

        {

            v.add(root.data);

        }

        m.put(horizontal_dist,v);

        verticalOrder(root.left, horizontal_dist - 1, m);

        verticalOrder(root.right, horizontal_dist + 1, m);

    }


    // Top-view of a binary tree

    public static class Pair {

        Node node;

        int hd;

    

        Pair(Node node, int hd) {

            this.node = node;

            this.hd = hd;

        }

    }

    

    static ArrayList<Integer> topView(Node root)

    {

        ArrayList<Integer> ans = new ArrayList<>(); 

        if(root == null) return ans;

        Map<Integer, Integer> map = new TreeMap<>();

        Queue<Pair> q = new LinkedList<Pair>();

        q.add(new Pair(root, 0)); 

        while(!q.isEmpty()) {

            Pair it = q.remove();

            int hd = it.hd; 

            Node temp = it.node; 

            if(map.get(hd) == null) map.put(hd, temp.data); 

            if(temp.left != null) {

                

                q.add(new Pair(temp.left, hd - 1)); 

            }

            if(temp.right != null) {

                

                q.add(new Pair(temp.right, hd + 1)); 

            }

        }

    

        for (Map.Entry<Integer,Integer> entry : map.entrySet()) {

            ans.add(entry.getValue()); 

        }

        return ans; 

    }


    // Bottom-View of Binary Tree

   

    public static ArrayList <Integer> bottomView(Node root)

    {

        ArrayList<Integer> ans = new ArrayList<>(); 

        if(root == null) return ans;

        Map<Integer, Integer> map = new TreeMap<>();

        Queue<Node> q = new LinkedList<Node>();

        root.hd = 0;

        q.add(root); 

        while(!q.isEmpty()) {

            Node temp = q.remove();

            int hd = temp.hd; 

            map.put(hd, temp.data); 

            if(temp.left != null) {

                temp.left.hd = hd - 1; 

                q.add(temp.left); 

            }

            if(temp.right != null) {

                temp.right.hd = hd + 1; 

                q.add(temp.right); 

            }

        }

        

        for (Map.Entry<Integer,Integer> entry : map.entrySet()) {

            ans.add(entry.getValue()); 

        }

        return ans; 

    }


    // Right View of binary tree

    public static List<Integer> rightSideView(Node root) {

        List<Integer> result = new ArrayList<Integer>();

        rightView(root, result, 0);

        return result;

    }

    

    public static void rightView(Node curr, List<Integer> result, int currDepth){

        if(curr == null){

            return;

        }

        if(currDepth == result.size()){

            result.add(curr.data);

        }

        

        rightView(curr.right, result, currDepth + 1);

        rightView(curr.left, result, currDepth + 1);

        

    }

    //Left-side view

    public static List<Integer> leftSideView(Node root) {

        List<Integer> result = new ArrayList<Integer>();

        leftView(root, result, 0);

        return result;

    }

    

    public static void leftView(Node curr, List<Integer> result, int currDepth){

        if(curr == null){

            return;

        }

        if(currDepth == result.size()){

            result.add(curr.data);

        }

        

        leftView(curr.left, result, currDepth + 1);

        leftView(curr.right, result, currDepth + 1);

    }


    // Check if bianry tree is symmetric or not

    static boolean isSymmetricUtil(Node  root1, Node  root2) {

        if (root1 == null || root2 == null)

          return root1 == root2;

        return (root1 . data == root2 . data) && isSymmetricUtil(root1 . left, root2 . 

        right) && isSymmetricUtil(root1 . right, root2 . left);

      }

      static boolean isSymmetric(Node  root) {

        if (root==null) return true;

        return isSymmetricUtil(root . left, root . right);

      }

      

      // Print root to node path

      static boolean getPath(Node root, ArrayList < Integer > arr, int x) {

         

        if (root == null)

            return false;

        arr.add(root.data);

        if (root.data == x)

            return true;

        if (getPath(root.left, arr, x) ||

            getPath(root.right, arr, x))

            return true;

        arr.remove(arr.size() - 1);

        return false;

    }


    public static void  printPath(Node root, int node_data)

    {

        ArrayList < Integer > arr = new ArrayList < > ();

        boolean res;

        res = getPath(root, arr, node_data);


        System.out.print("The Root to node path is: ");

        for (int it: arr) {

            System.out.print(it + " ");

        }

    }


    // lowest common ancestor of binary tree

     public static Node lowestCommonAncestor(Node root, Node p, Node q) {

        if (root == null || root == p || root == q) {

            return root;

        }

        Node left = lowestCommonAncestor(root.left, p, q);

        Node right = lowestCommonAncestor(root.right, p, q);


        //result

        if(left == null) {

            return right;

        }

        else if(right == null) {

            return left;

        }

        else { //both left and right are not null, we found our result

            return root;

        }

    }


    // Maximum width of a binary tree

    public static int widthOfBinaryTree(Node root) {

        if(root == null) return 0;

        int ans = 0;

        Queue<Pair> q = new LinkedList<>(); 

        q.offer(new Pair(root, 0)); 

        while(!q.isEmpty()){

            int size = q.size();

            int mmin = q.peek().hd;    //to make the id starting from zero  

            int first = 0,last = 0;   //hd code written in Pair class

            for(int i=0; i<size; i++){

                int cur_id = q.peek().hd-mmin;

                Node node = q.peek().node;

                q.poll();

                if(i==0) first = cur_id;

                if(i==size-1) last = cur_id;

                if(node.left != null)

                    q.offer(new Pair(node.left, cur_id*2+1));

                if(node.right != null) 

                    q.offer(new Pair(node.right, cur_id*2+2));

            }

            ans = Math.max(ans, last-first+1);

        }

        return ans;

    }


    //Children sum property in binary tree

    static void reorder(Node  root) {

        if (root == null) return;

        int child = 0;

        if (root . left!=null) {

          child += root . left . data;

        }

        if (root . right!=null) {

          child += root . right . data;

        }

      

        if (child < root . data) {

          if (root . left!=null) root . left . data = root . data;

          else if (root . right!=null) root . right . data = root . data;

        }

      

        reorder(root . left);

        reorder(root . right);

      

        int tot = 0;

        if (root . left!=null) tot += root . left . data;

        if (root . right!=null) tot += root . right . data;

        if (root . left!=null || root . right!=null) root . data = tot;

      }

      static void changeTree(Node  root) {

        reorder(root);

      }


      //print nodes at distance k

      static void printkdistanceNodeDown(Node node, int k)

      {

          // Base Case

          if (node == null || k < 0)

              return;

    

          // If we reach a k distant node, print it

          if (k == 0)

          {

              System.out.print(node.data);

              System.out.println("");

              return;

          }

    

          // Recur for left and right subtrees

          printkdistanceNodeDown(node.left, k - 1);

          printkdistanceNodeDown(node.right, k - 1);

      }

    

      // Prints all nodes at distance k from a given target node.

      // The k distant nodes may be upward or downward.This function

      // Returns distance of root from target node, it returns -1

      // if target node is not present in tree rooted with root.

      static int printkdistanceNode(Node node, Node target, int k)

      {

          // Base Case 1: If tree is empty, return -1

          if (node == null)

              return -1;

    

          // If target is same as root.  Use the downward function

          // to print all nodes at distance k in subtree rooted with

          // target or root

          if (node == target)

          {

              printkdistanceNodeDown(node, k);

              return 0;

          }

    

          // Recur for left subtree

          int dl = printkdistanceNode(node.left, target, k);

    

          // Check if target node was found in left subtree

          if (dl != -1)

          {

                

              // If root is at distance k from target, print root

              // Note that dl is Distance of root's left child from

              // target

              if (dl + 1 == k)

              {

                  System.out.print(node.data);

                  System.out.println("");

              }

                

              // Else go to right subtree and print all k-dl-2 distant nodes

              // Note that the right child is 2 edges away from left child

              else

                  printkdistanceNodeDown(node.right, k - dl - 2);

    

              // Add 1 to the distance and return value for parent calls

              return 1 + dl;

          }

    

          // MIRROR OF ABOVE CODE FOR RIGHT SUBTREE

          // Note that we reach here only when node was not found in left

          // subtree

          int dr = printkdistanceNode(node.right, target, k);

          if (dr != -1)

          {

              if (dr + 1 == k)

              {

                  System.out.print(node.data);

                  System.out.println("");

              }

              else

                  printkdistanceNodeDown(node.left, k - dr - 2);

              return 1 + dr;

          }

    

          // If target was neither present in left nor in right subtree

          return -1;

      }

      

      //count total number of nodes in complete binary tree

      static void inOrderTrav(Node  curr, int count[]) {

        if (curr == null)

          return;

      

        count[0]++;

        inOrderTrav(curr . left, count);

        inOrderTrav(curr . right, count);

      }


      // Serialise and De-Serialise

      public static String serialize(Node root) {

        if (root == null) return "";

        Queue<Node> q = new LinkedList<>();

        StringBuilder res = new StringBuilder();

        q.add(root);

        while (!q.isEmpty()) {

            Node node = q.poll();

            if (node == null) {

                res.append("n ");

                continue;

            }

            res.append(node.data + " ");

            q.add(node.left);

            q.add(node.right);

        }

        return res.toString();

    }


    public static Node deserialize(String data) {

        if (data == "") return null;

        Queue<Node> q = new LinkedList<>();

        String[] values = data.split(" ");

        Node root = new Node(Integer.parseInt(values[0]));

        q.add(root);

        for (int i = 1; i < values.length; i++) {

            Node parent = q.poll();

            if (!values[i].equals("n")) {

                Node left = new Node(Integer.parseInt(values[i]));

                parent.left = left;

                q.add(left);

            }

            if (!values[++i].equals("n")) {

                Node right = new Node(Integer.parseInt(values[i]));

                parent.right = right;

                q.add(right);

            }

        }

        return root;

    }


    //Morris inorder traversal of a binary tree

    public static List<Integer> MorrisInorderTraversal(Node root) {

        List<Integer> inorder = new ArrayList<Integer>(); 

        

        Node cur = root; 

        while(cur != null) {

            if(cur.left == null) {

                inorder.add(cur.data); 

                cur = cur.right; 

            }

            else {

                Node prev = cur.left; 

                while(prev.right != null && prev.right != cur) {

                    prev = prev.right; 

                }

                

                if(prev.right == null) {

                    prev.right = cur;

                    cur = cur.left; 

                }

                else {

                    prev.right = null; 

                    inorder.add(cur.data); 

                    cur = cur.right; 

                }

            }

        }

        return inorder; 

    }


    //Morris preorder traversal of a binary tree

    public static ArrayList < Integer > MorrisPreorderTraversal(Node root) {

        ArrayList < Integer > preorder = new ArrayList < > ();

        Node cur = root;

        while (cur != null) {

            if (cur.left == null) {

                preorder.add(cur.data);

                cur = cur.right;

            } else {

                Node prev = cur.left;

                while (prev.right != null && prev.right != cur) {

                    prev = prev.right;

                }


                if (prev.right == null) {

                    prev.right = cur;

                    preorder.add(cur.data);

                    cur = cur.left;

                } else {

                    prev.right = null;

                    cur = cur.right;

                }

            }

        }

        return preorder;

    }


    //Flatten Binary Tree to Linked List 

    //  using recursion


    static Node prev = null;

    static void flatten(Node  root) {

      if (root == null) return;


      flatten(root . right);

      flatten(root . left);


      root . right = prev;

      root . left = null;

      prev = root;

    }


    public static void BinaryToLinkedList_recursion(Node root)

    {

        flatten(root);

        while(root.right!=null)

    {

      System.out.print(root.data+"->");

      root=root.right;

    }

    System.out.print(root.data);

    }

    //using stack and using morris traversal are also there the code is commented

    /*

     using stack

     static Node prev = null;

    static void flatten(Node  root) {

  if (root == null) return;

  Stack < Node  > st=new Stack<>();

  st.push(root);

  while (!st.isEmpty()) {

    Node  cur = st.peek();

    st.pop();


    if (cur . right != null) {

      st.push(cur . right);

    }

    if (cur . left != null) {

      st.push(cur . left);

    }

    if (!st.isEmpty()) {

      cur . right = st.peek();

    }

    cur . left = null;

  }


}


// using morris travesal

    static Node prev = null;

    static void flatten(Node root) {

        Node cur = root;

while (cur!=null)

{

if(cur.left!=null)

{

Node pre = cur.left;

while(pre.right!=null)

{

pre = pre.right;

}

pre.right = cur.right;

cur.right = cur.left;

cur.left = null;

}

cur = cur.right;

}

    }


     */


    // Binary Search Tree (BST)

    // SEARCH IN BST

    public static Node searchBST(Node root, int val) {

        if (root == null || root.data == val) {

            return root;

        }


        if (val < root.data) {

            return searchBST(root.left, val);

        }


        return searchBST(root.right, val);

    }


    public static void printsearchBST(Node root,int target)

    {

        root = searchBST(root, target);

        if (root != null) {

            System.out.println(target + " found in the BST.");

        } else {

            System.out.println(target + " not found in the BST.");

        }

    }


    // CEIL IN BST

    public static int findCeil(Node root,int key)

    {

        int ceil = -1;

        while(root!=null)

        {

            if(root.data==key)

            {

                ceil = root.data;

                return ceil;

            }

            if(key>root.data)

            {

                root=root.right;

            }

            else

            {

                ceil=root.data;

                root=root.left;

            }

        }

        return ceil;

    }


    // Insert node in BST

    public static Node insertIntoBST(Node root,int val)

    {

        if(root==null) return new Node(val);

        Node cur = root;

        while(true)

        {

            if(cur.data<=val)

            {

                if(cur.right!=null) cur=cur.right;

                else{

                    cur.right=new Node(val);

                    break;

                }

            }

            else{

                

                if(cur.left!=null) cur=cur.left;

                else{

                    cur.left=new Node(val);

                    break;

                }

            }

        }

        return root;

    }

    

    public static void main(String[] args) {

        Scanner scanner = new Scanner(System.in);

        BinaryTree bt = new BinaryTree();

        

        System.out.print("Enter root node value: ");

        int rootValue = scanner.nextInt();

        Node root = new Node(rootValue);


        root.left = bt.buildTree(scanner, "left", rootValue);

        root.right = bt.buildTree(scanner, "right", rootValue);


        System.out.println("Tree construction complete.");

        levelorder(root);

        System.out.println(preorderUsingStack(root));

        System.out.println(inorderUsingStack(root));

        System.out.println(postorderUsing2Stack(root));

        System.out.println(postorderUsing1Stack(root));

        ArrayList<Integer> preorderArrayList = new ArrayList<Integer>();

        ArrayList<Integer> inorderArrayList = new ArrayList<Integer>();

        ArrayList<Integer> postorderArrayList = new ArrayList<Integer>();

        preInPost_traversal_in_one(root, preorderArrayList, inorderArrayList, postorderArrayList);

        System.out.print("The preorder traversal is: ");

        for (Integer pre : preorderArrayList) {

            System.out.print(pre+" ");

        }

        System.out.println();

        System.out.print("The inorder traversal is: ");

        for (Integer in : inorderArrayList) {

            System.out.print(in+" ");

        }

        System.out.println();

        System.out.print("The postorder traversal is: ");

        for (Integer post : postorderArrayList) {

            System.out.print(post+" ");

        }

        System.out.println();

        System.out.println("The depth of your tree is: "+maxDepthOfBinaryTree(root));

        boolean balanced_var = isBalancedBinaryTree_boolean_value(root);

        System.out.println(balanced_var);

        System.out.println("The diameter of given binary tree is: "+diameterofbinarytree(root));

        System.out.println("The maximum path sum is: "+maxPathSum(root));

        System.out.println("The zigZag Traversal is: "+zigZagTraversal(root));

        System.out.println("The boundary traversal is as below:");

        boundaryTraversal(root);

        System.out.println();

        System.out.println("The vertical order traversal is as below:");

        TreeMap<Integer, Vector<Integer>> m = new TreeMap<>();

        int hd = 0;

        verticalOrder(root, hd, m);

        for (Map.Entry<Integer,Vector<Integer>> e : m.entrySet()) {

            System.out.println(e.getValue());

        }

        System.out.println("Top view traversal is :");

        System.out.println(topView(root));

        System.out.println("Bottom view traversal is :");

        System.out.println(bottomView(root));

        System.out.println("The right-side view is:");

        System.out.println(rightSideView(root));

        System.out.println("The left-side view is:");

        System.out.println(leftSideView(root));

        System.out.println("The binary tree is symmetric: "+isSymmetric(root));

        printPath(root, 7);

        System.out.println();

        //System.out.println("The lowest common ancestor is: "+lowestCommonAncestor(root, root.left.left, root.left.right.right).data);

        System.out.println("The maximum width of a binary tree is: "+widthOfBinaryTree(root));

        //System.out.println("Level order traversal of tree after children sum property is: ");

        //changeTree(root);

        //levelorder(root);

        //System.out.println("The nodes at distance k is: ");

        //Node target = root.left.right;

        //printkdistanceNode(root, target, 2);

        //System.out.println("--");

        int count[]=new int[1];

        inOrderTrav(root, count);

        System.out.println("The total number of nodes in the given complete binary tree are: "+count[0]);

        System.out.println(serialize(root));

        System.out.println(deserialize(serialize(root)).data);

        System.out.println(MorrisInorderTraversal(root));

        System.out.println(MorrisPreorderTraversal(root));

        //BinaryToLinkedList_recursion(root);

        printsearchBST(root, 8);

        System.out.println(findCeil(root, 4));

        insertIntoBST(root, 0);

        levelorder(root);

        scanner.close();

    }

}



  

Good thoughtful question on Binary search on answers

Problem link:  https://leetcode.com/problems/maximize-score-of-numbers-in-ranges/description/ Solution: //import java.util.Arrays; class So...