二叉树先序遍历

二叉树先序遍历

一 先序遍历
顺序为:跟节点->左子树->右子树
先遍历跟节点,然后遍历左子树,最后遍历右子树,以此轮推,知道遍历完所有节点。

                            6
                     -------------
                     4           8
                 --------     -------
                 2      5     7     9
              --------
              1      3

如上二叉树先序遍历结果为:6 4 2 1 3 5 8 7 9
遍历逻辑如下:
1.先遍历跟节点 6
2.访问跟节点6的左子树,节点4
3.访问节点4的左子树,节点2
4.访问节点2的左子树,节点1
5.节点1没有左子树了,转而访问节点2的右子树,节点3
6.此时节点4左子树上的所有节点(2,1,3)都访问过了,转而访问节点4的右子树,节点5
7.此时节点6的左子树上所有节点(4, 2, 1, 3, 5)都访问过了,转而访问节点6的右子树,节点8
8.访问节点8的左子树,节点7
9.节点7没有子节点,则节点8的左子树上的所有节点(7)都访问过了,转而访问节点8的右子树,节点9
10.至此二叉树的所以节点(6 4 2 1 3 5 8 7 9) 已全部访问,则遍历结束

先序遍历的两种实现方法:递归实现、迭代实现

    // 树节点定义如下
    public class TreeNode
    {
        public int val;
        public TreeNode left;
        public TreeNode right;
        public TreeNode(int val = 0, TreeNode left = null, TreeNode right = null)
        {
            this.val = val;
            this.left = left;
            this.right = right;
        }
    }

递归实现代码如下

        // 递归实现
        public IList<int> PreorderTraversal(TreeNode root)
        {
            // 列表存储访问的节点值
            IList<int> list = new List<int>();
            // 调用递归函数
            PreorderTraversal(root, list);
            return list;
        }

        public void PreorderTraversal(TreeNode root, IList<int> list)
        {
            if (null == root)
            {
                return;
            }

            // 访问节点自身
            list.Add(root.val);

            // 访问节点左子树
            PreorderTraversal(root.left, list);

            // 访问节点右子树
            PreorderTraversal(root.right, list);
        }

迭代实现代码如下

        public IList<int> PreorderTraversal2(TreeNode root)
        {
            // 列表存储访问的节点值
            IList<int> list = new List<int>();
            if (null == root)
            {
                return list;
            }

            // 以栈结构(先进后出)来构建节点访问次序
            Stack<TreeNode> stack = new Stack<TreeNode>();
            // 先将跟节点入栈
            stack.Push(root);
            while (stack.Count > 0)
            {
                // 节点出栈(为最后一次放入的节点)
                TreeNode node = stack.Pop();

                // 将节点存入列表
                list.Add(node.val);

                // 因为子树的访问顺序为,先左后右,栈的特性为先进后出
                // 则需要先放入右子树,然后放入左子树,从栈中取出顺序则
                // 为先取出左子树,后取出右子树

                // 如果右子树不为空,则将右子树入栈
                if (null != node.right)
                {
                    stack.Push(node.right);
                }
                // 如果左子树不为空,则将左子树入栈
                if (null != node.left)
                {
                    stack.Push(node.left);
                }
            }

            return list;
        }

至此二叉树先序遍历的原理以及实现代码均已奉上

你可能感兴趣的:(数据结构,二叉树,二叉树先序遍历,二叉树遍历)