代码随想录算法训练营第十四天|144.二叉树的前序遍历、145.二叉树的后序遍历、94.二叉树的中序遍历

144.二叉树的前序遍历

递归:

public class Solution {
    public IList PreorderTraversal(TreeNode root) {
        var i=new List();
        if(root==null)
        {
            return i;
        }
       Pre(root,i);
        return i;
}
public void Pre(TreeNode cur,IList i)
{
    if(cur==null)
    {
        return;
    }
    i.Add(cur.val);
    Pre(cur.left,i);
    Pre(cur.right,i);
}
}

创建一个储存二叉树值得列表,然后排除特殊情况——头结点为空,直接返回空列表,如果不为空则运行递归的函数部分。递归部分则判断传入的的该节点是否为空,为空直接返回给上一层,如果不为空则将自己加入到列表里,然后递归自己的左右节点,前序遍历的顺序就是中左右。

迭代:

public class Solution {
    public IList PreorderTraversal(TreeNode root) {
        var st=new Stack();
        var ans=new List();
        if(root==null)
        {
            return ans;
        }
        st.Push(root);
        while(st.Count!=0)
        {
            var cur=st.Pop();
            ans.Add(cur.val);
            if(cur.right!=null)
            {
                st.Push(cur.right);
            }
            if(cur.left!=null)
            {
                st.Push(cur.left);
            }
        }
        return ans;
    }
}

与递归不同的是,迭代不用反复调用自身而是需要用到栈来辅助,同样处理头结点为空的情况,首先将根节点压入栈中,进行一个While()循环,如果栈不为零则一直循环,将栈的元素弹出一个,记录并加入Ans列表,然后依次判断是否有右节点和左节点,因为栈是先进后出,前序遍历是中左右,左在前所以要后进入栈才能先出来,直到While循环结束返回Ans列表即可。

145.二叉树的后序遍历

递归:

public class Solution {
    public IList PostorderTraversal(TreeNode root) {
        var i=new List();
        if(root==null)
        {
            return i;
        }  
        Post(root,i);
        return i;
    }
    public void Post(TreeNode cur,IList i)
    {
        if(cur==null)
        {
            return;
        }
        Post(cur.left,i);
        Post(cur.right,i);
        i.Add(cur.val);
    }
}

后序遍历的顺序是左右中,所以只需在前序遍历的递归部分的基础先递归自己的左节点然后再是自己的右节点,都完成以后再将自己(中节点)加入到列表里,最后返回出去。

迭代:

public class Solution {
    public IList PostorderTraversal(TreeNode root) {
        var st=new Stack();
        var ans=new List();
        if(root==null)
        {
            return ans;
        }
        st.Push(root);
        while(st.Count!=0)
        {
            var cur=st.Pop();
            ans.Add(cur.val);
            if(cur.left!=null)
            {
                st.Push(cur.left);
            }
            if(cur.right!=null)
            {
                st.Push(cur.right);
            }
        }
        ans.Reverse(0,ans.Count());
        return ans;
    }
}

后序遍历的顺序是左右中,而前序遍历的顺序是中左右,对左右叶子节点的入栈顺序稍加调换可以实现中右左,然后将其得到的结果Reverse()翻转一下就得到了左右中的后续遍历。

94.二叉树的中序遍历

递归:

public class Solution {
    public IList InorderTraversal(TreeNode root) {
        var i=new List();
        if(root==null)
        {
            return i;
        }
        Mid(root,i);
        return i;
    }
    public void Mid(TreeNode cur,IList i)
    {
        if(cur==null)
        {
            return;
        }
        Mid(cur.left,i);
        i.Add(cur.val);
        Mid(cur.right,i);
    }
}

 将递归函数部分的顺序改为中序遍历的顺序,即左中右。

迭代:

public class Solution {
    public IList InorderTraversal(TreeNode root) {
         var st=new Stack();
        var ans=new List();
        var cur=root;
        if(root==null)
        {
            return ans;
        }
        while(st.Count!=0||cur!=null)
        {
            if(cur!=null)
            {
                st.Push(cur);
                cur=cur.left;
            }else
            {
                cur=st.Pop();
                ans.Add(cur.val);
                cur=cur.right;
            }
        }
        return ans;
    }
}

同样需要创建一个栈,排除头结点为空情况,While循环,栈或者当前节点不为空均继续循环,如果当前节点不为空就压入栈中,然后压入左节点,如果当天节点为空,栈弹出一个节点赋值给当前节点,Ans列表加入当前节点的值,然后右节点变成了当前节点重复While循环的操作,知道不符合循环条件跳出,最终返回Ans列表。

你可能感兴趣的:(算法,开发语言,数据结构,c#,leetcode)