private void button14_Click(object sender, EventArgs e)
        {
            //            Input Tree
            //       A
            //      / \
            //     B   C
            //    / \   \
            //   D   E   F


            //Output Tree
            //       A--->NULL
            //      / \
            //     B-->C-->NULL
            //    / \   \
            //   D-->E-->F-->NULL

            //Build the tree
            NodeWithNext <char> root = new NodeWithNext <char>('A');

            root.Left  = new NodeWithNext <char>('B');
            root.Right = new NodeWithNext <char>('C');

            root.Left.Left   = new NodeWithNext <char>('D');
            root.Left.Right  = new NodeWithNext <char>('E');
            root.Right.Right = new NodeWithNext <char>('F');

            //set for root
            root.Next = (root.Left != null) ? root.Left : root.Right;
            PopulateNeightboursUsingDFS(root);

            //test
            NodeWithNext <char> test  = root.Right.Next;      //d
            NodeWithNext <char> test2 = root.Left.Right.Next; //f
        }
 public NodeWithNext(T value)
 {
     this.Data  = value;
     this.Left  = null;
     this.Right = null;
     this.Next  = null;
 }
        private void button5_Click(object sender, EventArgs e)
        {
            //            Input Tree
            //       A
            //      / \
            //     B   C
            //    / \   \
            //   D   E   F


            //Output Tree
            //       A--->NULL
            //      / \
            //     B-->C-->NULL
            //    / \   \
            //   D-->E-->F-->NULL

            //Build the tree
            NodeWithNext <char> root = new NodeWithNext <char>('A');

            root.Left  = new NodeWithNext <char>('B');
            root.Right = new NodeWithNext <char>('C');

            root.Left.Left   = new NodeWithNext <char>('D');
            root.Left.Right  = new NodeWithNext <char>('E');
            root.Right.Right = new NodeWithNext <char>('F');

            root.Next = null;

            PopulateNextPointerUsingDFSNonCompleteTrees(root);

            //test
            NodeWithNext <char> test  = root.Right.Next;      //null
            NodeWithNext <char> test2 = root.Left.Right.Next; //f
        }
        //Logic Travers in this fashio (right, current, left)
        //We need to pass value from children to parent (bubble up ) so we have to use return varaible
        //But here return variable will not work because for null parent, we still need to preserve lastvisited node..so use static variable or use reference to get the lastvisited node
        private void PopulateNextPointToInOrderSuccessor(NodeWithNext <char> root, ref NodeWithNext <char> lastvisited)
        {
            if (root != null)
            {
                PopulateNextPointToInOrderSuccessor(root.Right, ref lastvisited);

                //current
                root.Next   = lastvisited;
                lastvisited = root;

                PopulateNextPointToInOrderSuccessor(root.Left, ref lastvisited);
            }
        }
        //http://www.geeksforgeeks.org/connect-nodes-at-same-level-with-o1-extra-space/
        //Logic:  Traverse in (next, left, right) fashion
        //use helper function to get next for right child and for left child when right is null
        //Assumption: root should have next set before calling this function

        private void PopulateNextPointerUsingDFSNonCompleteTrees(NodeWithNext <char> root)
        {
            if (root == null)
            {
                return;
            }

            //Logic:  Traverse in (next, left, right) fashion
            if (root.Next != null)
            {
                PopulateNextPointerUsingDFSNonCompleteTrees(root.Next);
            }

            if (root.Left != null)
            {
                //set the next pointer of root.Left and root.Right and call the recurssive fu for left

                if (root.Right != null)
                {
                    root.Left.Next  = root.Right;
                    root.Right.Next = GetNextNode(root);
                }
                else
                {
                    root.Left.Next = GetNextNode(root);
                }

                // Recursively call for next level nodes.  Note that we call only
                //for left child. The call for left child will call for right child */
                PopulateNextPointerUsingDFSNonCompleteTrees(root.Left);
            }
            else if (root.Right != null)
            {
                //set the next pointer for right child and then call recurssion
                root.Right.Next = GetNextNode(root);

                PopulateNextPointerUsingDFSNonCompleteTrees(root.Right);
            }
            else
            {
                PopulateNextPointerUsingDFSNonCompleteTrees(GetNextNode(root));
            }
        }
        private void PopulateNextPointerUsingBFS(NodeWithNext <char> root)
        {
            if (root == null)
            {
                return;
            }

            int level = 0;
            Queue <QueueCustomNode <char> > myqueue = new Queue <QueueCustomNode <char> >();
            QueueCustomNode <char>          level0  = new QueueCustomNode <char>(root, level);

            //set the root next pointer
            root.Next = root.Left;
            myqueue.Enqueue(level0);

            while (myqueue.Count != 0)
            {
                QueueCustomNode <char> parent = myqueue.Dequeue();
                //set the parent next pointer
                //check if there is no next element in the queue or the next element doesn't belong to this level
                level = parent.Level + 1;
                if (myqueue.Count == 0 || myqueue.Peek().Level != parent.Level)
                {
                    parent.Node.Next = null;
                }
                else
                {
                    parent.Node.Next = myqueue.Peek().Node;
                }

                if (parent.Node.Left != null)
                {
                    myqueue.Enqueue(new QueueCustomNode <char>(parent.Node.Left, level));
                }

                if (parent.Node.Right != null)
                {
                    myqueue.Enqueue(new QueueCustomNode <char>(parent.Node.Right, level));
                }
            }
        }
        /* This function returns the leftmost child of nodes at the same level as p.
        *  This function is used to getNExt right of p's right child
        *  If right child of p is NULL then this can also be used for the left child */
        private NodeWithNext <char> GetNextNode(NodeWithNext <char> root)
        {
            NodeWithNext <char> runner = root.Next;

            while (runner != null)
            {
                if (runner.Left != null)
                {
                    return(runner.Left);
                }
                else if (runner.Right != null)
                {
                    return(runner.Right);
                }
                else
                {
                    runner = runner.Next;
                }
            }
            return(runner);
        }
        private void button3_Click(object sender, EventArgs e)
        {
            //            Input Tree
            //       A
            //      / \
            //     B   C
            //    / \    \
            //   D   E   G  F


            //Output Tree
            //       A--->NULL
            //      / \
            //     B-->C-->NULL
            //    / \   \
            //   D-->E-->G  F-->NULL

            //Build the tree

            //Imporant this logic won't work unless the tree is complete binary tree so make a complete binary tree
            NodeWithNext <char> root = new NodeWithNext <char>('A');

            root.Left  = new NodeWithNext <char>('B');
            root.Right = new NodeWithNext <char>('C');

            root.Left.Left  = new NodeWithNext <char>('D');
            root.Left.Right = new NodeWithNext <char>('E');

            root.Right.Left  = new NodeWithNext <char>('G');
            root.Right.Right = new NodeWithNext <char>('F');

            //set root's next
            root.Next = null;
            PopulateNextPointerUsingDFS(root);

            //test
            NodeWithNext <char> test  = root.Right.Next;      //null
            NodeWithNext <char> test2 = root.Left.Right.Next; //G
        }
        private void PopulateNeighboursUsingBFS(NodeWithNext <char> root)
        {
            if (root == null)
            {
                return;
            }

            Queue <NodeWithNext <char> > myqueue = new Queue <NodeWithNext <char> >();

            //set the root next pointer
            root.Next = root.Left;
            myqueue.Enqueue(root);

            while (myqueue.Count != 0)
            {
                NodeWithNext <char> parent = myqueue.Dequeue();
                //set the parent next pointer
                //check if there is no next element in the queue or the next element doesn't belong to this level
                if (myqueue.Count == 0)
                {
                    parent.Next = null;
                }
                else
                {
                    parent.Next = myqueue.Peek();
                }

                if (parent.Left != null)
                {
                    myqueue.Enqueue(parent.Left);
                }

                if (parent.Right != null)
                {
                    myqueue.Enqueue(parent.Right);
                }
            }
        }
        private void button6_Click(object sender, EventArgs e)
        {
            //            Input Tree
            //       A
            //      / \
            //     B   C
            //    / \   \
            //   D   E   F


            //Output Tree
            //       A--->NULL
            //      / \
            //     B-->C-->NULL
            //    / \   \
            //   D-->E-->F-->NULL

            //Build the tree
            NodeWithNext <char> root = new NodeWithNext <char>('A');

            root.Left  = new NodeWithNext <char>('B');
            root.Right = new NodeWithNext <char>('C');

            root.Left.Left   = new NodeWithNext <char>('D');
            root.Left.Right  = new NodeWithNext <char>('E');
            root.Right.Right = new NodeWithNext <char>('F');

            //last node should have null as next
            NodeWithNext <char> lastvisited = null;

            PopulateNextPointToInOrderSuccessor(root, ref lastvisited);

            //test
            NodeWithNext <char> test  = root.Right.Next;           //F
            NodeWithNext <char> test2 = root.Left.Right.Next;      //A
            NodeWithNext <char> test3 = root.Left.Right.Next.Next; //C
        }
        //Assumption:
        //The tree is complete binary tree
        //Root next's is already set (set root next outside this function
        private void PopulateNextPointerUsingDFS(NodeWithNext <char> root)
        {
            if (root == null)
            {
                return;
            }

            //The root next will be alredy fixed
            //set the next of the left and right child
            if (root.Left != null)
            {
                root.Left.Next = root.Right;
            }

            if (root.Right != null)
            {
                //see whether the parent has next pointer
                //if root.next == null then it is the rightmost node so set to null
                root.Right.Next = (root.Next == null) ? null : root.Next.Left;
            }

            PopulateNextPointerUsingDFS(root.Left);
            PopulateNextPointerUsingDFS(root.Right);
        }
 public QueueCustomNode(NodeWithNext <T> node, int level)
 {
     this.Node  = node;
     this.Level = level;
 }