예제 #1
0
        public static int FindMaxWidth(NodeBinTree <int> tree)
        {
            if (tree == null)
            {
                return(0);
            }

            var q = new Queue <NodeBinTree <int> >();

            q.Enqueue(tree);
            var max = 1;

            while (q.Count > 0)
            {
                var cnt = q.Count;
                max = Math.Max(max, cnt);

                for (int i = 0; i < cnt; i++)
                {
                    var n = q.Dequeue();
                    if (n.Left != null)
                    {
                        q.Enqueue(n.Left);
                    }
                    if (n.Right != null)
                    {
                        q.Enqueue(n.Right);
                    }
                }
            }

            return(max);
        }
예제 #2
0
        private static int CheckHeight(NodeBinTree <int> tree)
        {
            if (tree == null)
            {
                return(-1);
            }

            var leftHeight = CheckHeight(tree.Left);

            if (leftHeight == int.MinValue)
            {
                return(int.MinValue);
            }
            var rightHeight = CheckHeight(tree.Right);

            if (rightHeight == int.MinValue)
            {
                return(int.MinValue);
            }

            if (Math.Abs(leftHeight - rightHeight) > 1)
            {
                return(int.MinValue);
            }
            else
            {
                return(Math.Max(leftHeight, rightHeight) + 1);
            }
        }
예제 #3
0
        public void TestFindMaxWidthOfTree()
        {
            //GIVEN a binary tree
            // lets construct binary search tree - BST is used just to try, actually task is to find height of any binary tree

            /*
             *      definition of BST (binary search tree)
             *      - The left subtree of a node contains only nodes with keys lesser than the node’s key.
             *      - The right subtree of a node contains only nodes with keys greater than the node’s key.
             *      - The left and right subtree each must also be a binary search tree.
             *
             *                               5
             *                        /     \
             *                       3       8
             *                      / \     / \
             *                      1   4   7   12
             *                / \          /
             *              -1   2        6
             *              /
             *              -3
             *      -3 + ()
             */

            // 1st level
            var tree = new NodeBinTree <int>(5);

            // 2nd level
            var left3  = new NodeBinTree <int>(3);
            var right8 = new NodeBinTree <int>(8);

            tree.Left  = left3;
            tree.Right = right8;

            // 3rd level
            var left1   = new NodeBinTree <int>(1);
            var right4  = new NodeBinTree <int>(4);
            var left7   = new NodeBinTree <int>(7);
            var right12 = new NodeBinTree <int>(12);

            left3.Left   = left1;
            left3.Right  = right4;
            right8.Left  = left7;
            right8.Right = right12;

            // 4th level
            var leftm1 = new NodeBinTree <int>(-1);

            left1.Left   = leftm1;
            left1.Right  = new NodeBinTree <int>(2);
            right12.Left = new NodeBinTree <int>(6);

            //5th level
            leftm1.Left = new NodeBinTree <int>(-3);

            //WHEN
            var result = Solution.FindMaxWidth(tree);

            //THEN
            Assert.Equal(4, result);
        }
예제 #4
0
        public static Dictionary <int, int> CalculateVerticalSum(NodeBinTree <int> tree)
        {
            var verticalSums = new Dictionary <int, int>();

            Calc(tree, 0, verticalSums);

            return(verticalSums);
        }
예제 #5
0
 private static int GetHeight(NodeBinTree <int> root)
 {
     if (root != null)
     {
         return(1 + Math.Max(GetHeight(root.Left), GetHeight(root.Right)));
     }
     return(0);
 }
예제 #6
0
        public static void TestBreadthFirstTraversal()
        {
            //GIVEN

            #region create tree
            // 1st level
            var tree = new NodeBinTree <int>(5);

            // 2nd level
            var left3  = new NodeBinTree <int>(3);
            var right8 = new NodeBinTree <int>(8);
            tree.Left  = left3;
            tree.Right = right8;

            // 3rd level
            var left1   = new NodeBinTree <int>(1);
            var right4  = new NodeBinTree <int>(4);
            var left7   = new NodeBinTree <int>(7);
            var right12 = new NodeBinTree <int>(12);

            left3.Left   = left1;
            left3.Right  = right4;
            right8.Left  = left7;
            right8.Right = right12;

            // 4th level
            var leftm1 = new NodeBinTree <int>(-1);
            left1.Left  = leftm1;
            left1.Right = new NodeBinTree <int>(2);

            //5th level
            leftm1.Left = new NodeBinTree <int>(-3);
            #endregion

            //WHEN
            var result      = new List <int>();
            var doSomething = new Action <int> ((p) => result.Add(p));

            Solution <int> .BreadthFirstTraverse(tree, doSomething);

            //THEN
            var resultExpected = new List <int>()
            {
                5, 3, 8, 1, 4, 7, 12, -1, 2, -3
            };
            var isEqual = true;
            for (int i = 0; i < resultExpected.Count; i++)
            {
                if (resultExpected[i] != result[i])
                {
                    isEqual = false;
                    break;
                }
            }

            Assert.True(isEqual);
        }
예제 #7
0
        // string will be returned as a representation of a file

        // ------------- NON RECURSIVE solution, just for fun :) -----------------------
        public static string SerializeBinaryTreeToFileNoRecursion(NodeBinTree <int> tree)
        {
            // travers with BFS and create an array as a storage (similar to min/max heap)
            var index  = 0;
            var result = new string[100];             //TODO: create EnsureCapacity method

            var stackOfNodes   = new Stack <NodeBinTree <int> >();
            var stackOfIndexes = new Stack <int>();

            stackOfNodes.Push(tree);
            stackOfIndexes.Push(index);

            NodeBinTree <int> node;

            while (stackOfNodes.Count > 0)
            {
                node  = stackOfNodes.Pop();
                index = stackOfIndexes.Pop();

                if (node != null)
                {
                    result[index] = node.Value.ToString();

                    // basically, here we flatten tree to an array, if node is placed in i-th place
                    // it's left and right node should be placed in i*2 + 1 and i*2 + 2 respectively
                    if (node.Left != null || node.Right != null)
                    {
                        stackOfNodes.Push(node.Right); stackOfNodes.Push(node.Left);
                        stackOfIndexes.Push(index * 2 + 2); stackOfIndexes.Push(index * 2 + 1);                         // similarity with minheap implementation
                    }
                }
                else
                {
                    result[index] = "end";
                }
            }

            var stringResult = new StringBuilder();

            for (var i = 0; i < result.Length; i++)
            {
                if (result[i] == "end")
                {
                    break;
                }

                if (i > 0)
                {
                    stringResult.Append(',');
                }

                stringResult.Append(result[i] != null ? result[i].ToString() : "e");
            }

            return(stringResult.ToString());
        }
예제 #8
0
        public static bool IsTreeBalanced(NodeBinTree <int> tree)
        {
            var height = CheckHeight(tree);

            if (height == int.MinValue)
            {
                return(false);
            }

            return(true);
        }
예제 #9
0
        public static Node <int> Execute(NodeBinTree <int> tree)
        {
            var start = new Node <int>()
            {
                Value = tree.Value
            };

            Flatten(tree, start);

            return(start);
        }
예제 #10
0
        public static List <Node <T> > CreateListOfDepths(NodeBinTree <T> tree)
        {
            var listOfDepths = new List <Node <T> >();

            listOfDepths.Add(new Node <T>(tree.Value));            // added to index 0 - first level

            AddToLevel(listOfDepths, tree.Left, 1);
            AddToLevel(listOfDepths, tree.Right, 1);

            return(listOfDepths);
        }
예제 #11
0
        public void TestValidBST()
        {
            //GIVEN

            /*
             *                                5
             *                         /     \
             *                        3       8
             *                       / \     / \
             *                      1   4   7   12
             *                 / \
             *                -1  2
             *               /
             *              -3
             */

            // 1st level
            var tree = new NodeBinTree <int>(5);

            // 2nd level
            var left3  = new NodeBinTree <int>(3);
            var right8 = new NodeBinTree <int>(8);

            tree.Left  = left3;
            tree.Right = right8;

            // 3rd level
            var left1   = new NodeBinTree <int>(1);
            var right4  = new NodeBinTree <int>(4);
            var left7   = new NodeBinTree <int>(7);
            var right12 = new NodeBinTree <int>(12);

            left3.Left   = left1;
            left3.Right  = right4;
            right8.Left  = left7;
            right8.Right = right12;

            // 4th level
            var leftm1 = new NodeBinTree <int>(-1);

            left1.Left  = leftm1;
            left1.Right = new NodeBinTree <int>(2);

            //5th level
            // by adding this node we make tree unbalanced
            leftm1.Left = new NodeBinTree <int>(-3);

            //WHEN
            var result = Solution.IsValidBST(tree);

            //THEN
            Assert.True(result);
        }
예제 #12
0
        private static int Height(NodeBinTree <int> node)
        {
            if (node == null)
            {
                return(0);
            }

            var leftHeight = Height(node.Left);
            var rightHeigt = Height(node.Right);

            return(1 + Math.Max(leftHeight, rightHeigt));
        }
예제 #13
0
        public static void InOrderTraversal(NodeBinTree <T> node, Action <NodeBinTree <T> > visit = null)
        {
            if (node != null)
            {
                InOrderTraversal(node.Left, visit);
                if (visit != null)
                {
                    visit(node);
                }

                InOrderTraversal(node.Right, visit);
            }
        }
예제 #14
0
        private static string Serialize(NodeBinTree <int> node)
        {
            if (node == null)
            {
                return("e,");
            }

            //preorder traversal
            var value = node.Value;
            var left  = Serialize(node.Left);
            var right = Serialize(node.Right);

            return(value + "," + left + right);
        }
예제 #15
0
        private static NodeBinTree <int> GetBSTMinHeight(int[] array, int start, int end)
        {
            if (end < start)
            {
                return(null);
            }

            var mid = (start + end) / 2;
            NodeBinTree <int> root = new NodeBinTree <int>(array[mid]);

            root.Left  = GetBSTMinHeight(array, start, mid - 1);
            root.Right = GetBSTMinHeight(array, mid + 1, end);

            return(root);
        }
예제 #16
0
 private static void GetNthElement(NodeBinTree <int> node, int level, ref int nth)
 {
     if (node == null)
     {
         return;
     }
     if (level == 0)
     {
         nth = node.Value;
     }
     else
     {
         GetNthElement(node.Left, level - 1, ref nth);
         GetNthElement(node.Right, level - 1, ref nth);
     }
 }
예제 #17
0
        private static NodeBinTree <int> Deserialize(Queue <string> q)
        {
            var value = q.Dequeue();

            if (string.IsNullOrEmpty(value) || value == "e")
            {
                return(null);
            }

            //preorder traversal
            var node = new NodeBinTree <int>(int.Parse(value));

            node.Left  = Deserialize(q);
            node.Right = Deserialize(q);

            return(node);
        }
예제 #18
0
        private static void Diametar(NodeBinTree <int> node, ref int maxd, ref NodeBinTree <int> maxDiametarNode)
        {
            if (node == null)
            {
                return;
            }

            var d = 1 + Height(node.Left) + Height(node.Right);

            if (d > maxd)
            {
                maxd            = d;
                maxDiametarNode = node;
            }

            Diametar(node.Left, ref maxd, ref maxDiametarNode);
            Diametar(node.Right, ref maxd, ref maxDiametarNode);
        }
예제 #19
0
        public static bool IsValidBST(NodeBinTree <int> tree)
        {
            //version 1
            //InOrder traverse of BST should return numbers in ascending sorted order

            var prev = int.MinValue;
            Func <NodeBinTree <int>, bool> compare = (n) =>
            {
                if (prev > n.Value)
                {
                    return(false);
                }
                prev = n.Value;
                return(true);
            };

            return(IsValid(tree, compare));
        }
예제 #20
0
        public static int FindHeightBinaryTree(NodeBinTree <T> tree)
        {
            if (tree == null)
            {
                throw new ArgumentNullException("tree root cannot be null");
            }

            var leftHeight  = GetHeight(tree.Left);
            var rightHeight = GetHeight(tree.Right);

            if (leftHeight > rightHeight)
            {
                return(1 + leftHeight);
            }
            else
            {
                return(1 + rightHeight);
            }
        }
예제 #21
0
        private static int GetHeight(NodeBinTree <T> node)
        {
            if (node == null)
            {
                return(0);
            }

            var leftHeight  = GetHeight(node.Left);
            var rightHeight = GetHeight(node.Right);

            if (leftHeight > rightHeight)
            {
                return(1 + leftHeight);
            }
            else
            {
                return(1 + rightHeight);
            }
        }
예제 #22
0
        public static int Execute(NodeBinTree <int> tree)
        {
            // find max left height + max right height + 1
            var max             = 0;
            var maxDiametarNode = tree;

            Diametar(tree, ref max, ref maxDiametarNode);

            var leftH  = Height(maxDiametarNode.Left);
            var rightH = Height(maxDiametarNode.Right);

            int a = int.MinValue;
            int b = int.MinValue;

            GetNthElement(maxDiametarNode.Left, leftH - 1, ref a);
            GetNthElement(maxDiametarNode.Right, rightH - 1, ref b);

            return(Math.Abs(a - b));
        }
예제 #23
0
        private static void Calc(NodeBinTree <int> node, int hLevel, Dictionary <int, int> verticalSums)       // hLeve stands for horizontal level
        {
            if (node == null)
            {
                return;
            }

            if (!verticalSums.ContainsKey(hLevel))
            {
                verticalSums[hLevel] = node.Value;
            }
            else
            {
                verticalSums[hLevel] += node.Value;
            }

            Calc(node.Left, hLevel - 1, verticalSums);
            Calc(node.Right, hLevel + 1, verticalSums);
        }
예제 #24
0
        public void TestBinaryTreeToLinkedList(NodeBinTree <int> tree, Node <int> resultExpected)
        {
            // arrange, create test bin tree

            // act

            var result = Solution.Execute(tree);

            // assert

            var next         = result;
            var nextExpected = resultExpected;

            while (next != null)
            {
                Assert.Equal(nextExpected.Value, next.Value);
                next         = next.Next;
                nextExpected = nextExpected.Next;
            }
        }
예제 #25
0
        private static void AddToLevel(List <Node <T> > listOfDepths, NodeBinTree <T> node, int addToLevel)
        {
            if (node == null)
            {
                return;
            }

            var newNode = new Node <T>(node.Value);

            if (listOfDepths.Count - 1 >= addToLevel)
            {
                newNode.Next             = listOfDepths[addToLevel];
                listOfDepths[addToLevel] = newNode;
            }
            else
            {
                listOfDepths.Add(newNode);
            }

            AddToLevel(listOfDepths, node.Left, addToLevel + 1);
            AddToLevel(listOfDepths, node.Right, addToLevel + 1);
        }
예제 #26
0
        public void TestCounterClockwiseBinTree()
        {
            // arrange
            // create test tree
            // 0 raw
            var tree = new NodeBinTree <int>(1);

            // 1st raw
            tree.Left  = new NodeBinTree <int>(2);
            tree.Right = new NodeBinTree <int>(3);

            // 2nd raw
            tree.Right.Left  = new NodeBinTree <int>(5);
            tree.Right.Right = new NodeBinTree <int>(6);
            tree.Left.Left   = new NodeBinTree <int>(4);

            // 3rd raw
            tree.Left.Left.Left    = new NodeBinTree <int>(7);
            tree.Left.Left.Right   = new NodeBinTree <int>(8);
            tree.Right.Left.Left   = new NodeBinTree <int>(9);
            tree.Right.Right.Left  = new NodeBinTree <int>(10);
            tree.Right.Right.Right = new NodeBinTree <int>(11);

            var resultExpected = new List <int>()
            {
                1, 7, 8, 9, 10, 11, 3, 2, 4, 5, 6
            };

            // act
            var result = Solution.Execute(tree);

            // assert
            Assert.Equal(resultExpected.Count, result.Count);
            for (int i = 0; i < result.Count; i++)
            {
                Assert.Equal(resultExpected[i], result[i]);
            }
        }
예제 #27
0
        private static Node <int> Flatten(NodeBinTree <int> node, Node <int> parentNode)
        {
            var lastNode = parentNode;

            if (node.Left != null)
            {
                parentNode.Next = new Node <int>()
                {
                    Value = node.Left.Value
                };
                lastNode = Flatten(node.Left, parentNode.Next);
            }
            if (node.Right != null)
            {
                lastNode.Next = new Node <int>()
                {
                    Value = node.Right.Value
                };
                lastNode = Flatten(node.Right, lastNode.Next);
            }

            return(lastNode);
        }
예제 #28
0
 private static void AddLevel(NodeBinTree <int> root, int level, bool isRevert, List <int> ret)
 {
     if (root == null)
     {
         return;
     }
     if (level == 0)
     {
         ret.Add(root.Value);
     }
     if (level > 0)
     {
         if (isRevert)
         {
             AddLevel(root.Right, level - 1, isRevert, ret);
             AddLevel(root.Left, level - 1, isRevert, ret);
         }
         else
         {
             AddLevel(root.Left, level - 1, isRevert, ret);
             AddLevel(root.Right, level - 1, isRevert, ret);
         }
     }
 }
예제 #29
0
        private static bool IsValid(NodeBinTree <int> root, Func <NodeBinTree <int>, bool> compare)
        {
            if (root == null)
            {
                return(true);
            }

            if (!IsValid(root.Left, compare))
            {
                return(false);
            }

            if (!compare(root))
            {
                return(false);
            }

            if (!IsValid(root.Right, compare))
            {
                return(false);
            }

            return(true);
        }
예제 #30
0
        public void TestDiffTwoLongestRelatedNodesInBinTree()
        {
            // arrange
            var tree = new NodeBinTree <int>(1);

            tree.Left  = new NodeBinTree <int>(2);
            tree.Right = new NodeBinTree <int>(3);

            tree.Left.Left  = new NodeBinTree <int>(4);
            tree.Left.Right = new NodeBinTree <int>(5);

            tree.Left.Left.Right        = new NodeBinTree <int>(8);
            tree.Left.Right.Left        = new NodeBinTree <int>(6);
            tree.Left.Right.Right       = new NodeBinTree <int>(7);
            tree.Left.Right.Right.Right = new NodeBinTree <int>(10);

            tree.Left.Left.Right.Left = new NodeBinTree <int>(9);

            // act
            var result = Solution.Execute(tree);

            // assert
            Assert.Equal(1, result);
        }