Exemplo n.º 1
0
        public static void TreeTraversal()
        {
            //Define a binary tree.
            //            1
            //          /   \
            //         2     3
            //        / \   / \
            //       4  5   6  7 

            TreeNode root = new TreeNode(1);
            root.left = new TreeNode(2);
            root.right = new TreeNode(3);
            root.left.left = new TreeNode(4);
            root.left.right = new TreeNode(5);
            root.right.left = new TreeNode(6);
            root.right.right = new TreeNode(7);

            List<string> TreePath = root.ListBinaryTreePath1(root);
            List<string> TreePath2 = root.ListBinaryTreePath2(root);

            List<int> preResult = root.PreOrderTraversal(root);     //1, 2, 4, 5, 3, 6, 7
            List<int> preResult_i = root.PreOrderTraversal_Iterative1(root);
            List<int> preResult_i2 = root.PreOrderTraversal_Iterative2(root);

            List<int> inResult = root.InOrderTraversal(root);       //4, 2, 5, 1, 6, 3, 7
            List<int> inResult_i = root.InOrderTraversal_Iterative1(root); 

            List<int> postResult = root.PostOrderTraversal(root);   //4, 5, 2, 6, 7, 3, 1
            List<int> postResult_i = root.PostOrderTraversal_Iterative1(root);
            List<int> postResult_i2 = root.PostOrderTraversal_Iterative2(root);

            List<List<int>> levelResult = root.LevelOrderTraversal(root);
        }
Exemplo n.º 2
0
 //DFS: 后序 Post-order Traversal (Left -> Right -> ROOT) using Recursion
 public List<int> PostOrderTraversal(TreeNode root)
 {
     List<int> result = new List<int>();
     if (root != null)
     {
         result.AddRange(PostOrderTraversal(root.left));
         result.AddRange(PostOrderTraversal(root.right));
         result.Add(root.val);
     }
     return result;
 }
Exemplo n.º 3
0
        //---------------------------------------------------------------------
        //-------------     D F S  +  I T E R A T I V E     -------------------
        //---------------------------------------------------------------------
        //DFS: 先序 Pre-order Traversal, Stack
        public List<int> PreOrderTraversal_Iterative1(TreeNode root)
        {
            List<int> result = new List<int>();
            Stack<TreeNode> stack = new Stack<TreeNode>();

            stack.Push(root);
            while (stack.Count != 0)
            {
                root = stack.Pop();
                if (root != null)
                {
                    result.Add(root.val);
                    //Prevent pushing null node to enhance performance.
                    if (root.right != null) stack.Push(root.right);
                    if (root.left != null) stack.Push(root.left);
                }
            }
            return result;
        }
Exemplo n.º 4
0
        private static TreeNode AddToTree(int[] array, int start, int end)
        {
            if (end < start)
            {
                return null;
            }

            var mid = (start + end) / 2;
            var node = new TreeNode(array[mid]);
            node.SetLeftChild(AddToTree(array, start, mid - 1));
            node.SetRightChild(AddToTree(array, mid + 1, end));

            return node;
        }
Exemplo n.º 5
0
        public void SetRightChild(TreeNode right)
        {
            Right = right;

            if (right != null)
            {
                right.Parent = this;
            }
        }
Exemplo n.º 6
0
        public void SetLeftChild(TreeNode left)
        {
            Left = left;

            if (left != null)
            {
                left.Parent = this;
            }
        }
Exemplo n.º 7
0
        //DFS: 先序 Pre-order Traversal, Stack
        public List<int> PreOrderTraversal_Iterative2(TreeNode root)
        {
            List<int> result = new List<int>();
            Stack<TreeNode> stack = new Stack<TreeNode>();

            while (root != null || stack.Count != 0)
            {
                if (root != null)
                {
                    //Store root value first.
                    result.Add(root.val);
                    //Push right child into stack
                    stack.Push(root.right);
                    //Iterate left child first.
                    root = root.left;
                }
                else
                {
                    //if left child does not exist anymore, iterate the nearest right child.
                    root = stack.Pop();
                }

            }
            return result;
        }
Exemplo n.º 8
0
 //-------------     D F S  +  R E C U R S I V E  +  T O P - D O W N   -------------------
 //Solution 2: Recursion with helper function.
 //Key idea: While going deep during recursion, append the current node value into string "path", 
 //But at the same time, each level of recursion kepted its own version of "path"
 //Once reached leaf node, the "path" is done and add to string list "result"
 //该方案利用了string类型是绝对引用而List<string>里面装的是对象所以本质上是Reference Variable的特点,
 //用string类型的path确保每一层的path是独立的,但同时用List<string>类型的result确保所有的path都添加到一个List中并被返回
 private void ListBinaryTreePath2_Helper(TreeNode root, string path, List<string> result)
 {
     if (root.left == null && root.right == null) result.Add(path + root.val);
     if (root.left != null) ListBinaryTreePath2_Helper(root.left, path + root.val + "->", result);
     if (root.right != null) ListBinaryTreePath2_Helper(root.right, path + root.val + "->", result);
 }
Exemplo n.º 9
0
 public List<string> ListBinaryTreePath2(TreeNode root)
 {
     List<string> treePath = new List<string>();
     if (root != null) ListBinaryTreePath2_Helper(root, "", treePath);
     return treePath;
 }
Exemplo n.º 10
0
        //-------------     D F S  +  R E C U R S I V E  +  B O T T O M - U P   -------------------
        //Solution 1: Recursion without helper function.
        //List all root2leaf path in List<string>
        public List<string> ListBinaryTreePath1(TreeNode root)
        {
            //Note that every recursion create its own "result", so what was added in lower level (recursed into) has no affect to the current level.
            //Processed in Bottom-Up order, the current level will copy each entry (temp[i]) returned from lower level to its own result AFTER recurse bounce back.
            List<string> temp;
            List<string> result = new List<string>();

            //Null node (List count will remain 0 so NO value copied later.)
            if (root == null) return result;

            //Leaf node: Add current level (only one entry) and return
            if (root.left == null && root.right == null)
            {
                result.Add(root.val.ToString());
                return result;
            }

            //Recurse left subtree: Add current level value to every entry returned from the lower level.
            temp = ListBinaryTreePath1(root.left);
            for (int i = 0; i < temp.Count; i++) result.Add(root.val + "->" + temp[i]);

            //Recurse right subtree: Add current level value to every entry returned from the lower level.
            temp = ListBinaryTreePath1(root.right);
            for (int i = 0; i < temp.Count; i++) result.Add(root.val + "->" + temp[i]);

            return result;
        }
Exemplo n.º 11
0
        //---------------------------------------------------------------------
        //-------------     B F S  +  I T E R A T I V E     -------------------
        //---------------------------------------------------------------------
        //BFS: Level-order Traversal, Queue    
        public List<List<int>> LevelOrderTraversal(TreeNode root)
        {
            List<List<int>> result = new List<List<int>>();
            Queue<TreeNode> queue = new Queue<TreeNode>();

            queue.Enqueue(root);
            while (queue.Count != 0)
            {
                //Initiate a List<int> container for each level.
                List<int> level = new List<int>();
                //Store the static size as loop condition (this is a must because queue.Count is shrinking in each loop.)
                int size = queue.Count;
                for (int i = 0; i < size; i++)
                {
                    //Dequeue each node
                    root = queue.Dequeue();
                    //Save the node value
                    level.Add(root.val);
                    //And enqueue its child at the same time
                    if (root.left != null) queue.Enqueue(root.left);
                    if (root.right != null) queue.Enqueue(root.right);
                }
                //Save the level after dequeue all the node.
                result.Add(level);
            }
            return result;
        }
Exemplo n.º 12
0
        //DFS: 后序 Post-order Traversal, (Reversed Pre-order Traversal)
        public List<int> PostOrderTraversal_Iterative2(TreeNode root)
        {
            List<int> result = new List<int>();

            //Iterative: Reverse Pre-Order Traversal.
            Stack<TreeNode> stack = new Stack<TreeNode>();
            while (root != null || stack.Count != 0)
            {
                if (root != null)
                {
                    result.Add(root.val);
                    if (root.left != null) stack.Push(root.left);
                    root = root.right;
                }
                else
                {
                    root = stack.Pop();
                }
            }
            result.Reverse();
            return result;
        }
Exemplo n.º 13
0
        //DFS: 后序 Post-order Traversal, Stack
        public List<int> PostOrderTraversal_Iterative1(TreeNode root)
        {
            //Postorder traversal is more complicated to implement comparing to Preorder and Inorder.
            //At what point shall we visit the root node:
            //Condition 1: The root node has no child at all.
            //Condition 2: The root's child has already been visited.
            List<int> result = new List<int>();
            Stack<TreeNode> stack = new Stack<TreeNode>();
            if (root != null)
                stack.Push(root);
            TreeNode prev = null;
            while (stack.Count != 0)
            {
                root = stack.Peek();

                bool noChild = (root.left == null && root.right == null);
                bool doneChild = false;

                if (prev != null && (prev == root.left || prev == root.right))
                    doneChild = true;

                //直到没有child了或者child已经访问完了才把栈顶元素出栈
                if (noChild || doneChild)
                {
                    root = stack.Pop();
                    result.Add(root.val);
                    prev = root;
                }
                else
                {
                    if (root.right != null)
                        stack.Push(root.right);
                    if (root.left != null)
                        stack.Push(root.left);
                }
            }

            return result;
        }
Exemplo n.º 14
0
        //DFS: 中序 In-order Traversal, Stack
        public List<int> InOrderTraversal_Iterative1(TreeNode root)
        {
            //Step 1: Iterate left subtree, push left node into stack.
            //Step 2: Stop push until node is null (its parent has no left child).
            //Step 3: Pop current node, store the value.
            //Step 4: Switch to the right subtree and iterate right subtree,
            List<int> result = new List<int>();
            Stack<TreeNode> stack = new Stack<TreeNode>();

            //Stop loop when both root is null and stack is empty.
            while (root != null || stack.Count != 0)
            {
                if (root != null)
                {
                    //Store root for later use
                    stack.Push(root);
                    //Iterate left child first.
                    root = root.left;
                }

                else
                {
                    //If left child does not exist anymore, extract its parent
                    root = stack.Pop();
                    //And store parent value
                    result.Add(root.val);
                    //Then iterate its right child.
                    root = root.right;
                }
            }
            return result;
        }