39.二叉樹的後序遍歷

題目:二叉樹的後序遍歷

解析:
1.遞歸遍歷

public List<Integer> postorderTraversal1(TreeNode root) {
  List<Integer> list = new ArrayList<Integer>();
  if (root == null)  return list;
  postorder(root,list);
  return list;
 }
 public void postorder(TreeNode root, List<Integer> list){
  if (root != null){
   postorder(root.left,list);
   postorder(root.right,list);
   list.add(root.val);
  }
 }

2.非遞歸遍歷

在這裏插入圖片描述
①首先向棧中循環壓入左節點,即stack中數據爲1->2->4->8;
②判斷棧頂結點8是否有右孩子,如果沒有彈出8添加到list中,即棧stack中數據爲1->2->4,list中數據爲8;
③判斷棧頂結點4是否有右孩子,結點4有右孩子,將結點4的右孩子9壓入棧中,棧stack數據爲1->2->4->9;
④判斷棧頂結點9是否有右孩子,結點9沒有右孩子,彈出結點9加入list中,棧stack中的數據爲1->2->4,list中的數據爲8->9;
⑤判斷棧頂元素4是否有結點,注意此時要加上該節點的右孩子之前是否被訪問過的限定條件,即在上一步驟記錄彈出的結點last=9。此時由於棧頂4的右孩子被訪問過,因此棧頂元素不再加入list中,直接彈出即可;


循環判斷棧頂元素是否有右孩子或棧頂元素的右孩子是否被訪問過,如果有則先壓入棧中,如果沒有則直接彈出加入list中。

public List<Integer> postorderTraversal2(TreeNode root) {
  List<Integer> list = new ArrayList<Integer>();
  if (root == null)  return list;
  Stack<TreeNode> stack = new Stack<TreeNode>();
  TreeNode pnode = null;
  while (root != null || !stack.isEmpty()){
          //循環將左孩子的結點壓入棧
   while(root != null){
    stack.push(root);
    root = root.left;
   }
   TreeNode node = stack.peek();
         //如果棧中壓入的結點的右孩子爲空,或其右孩子爲上一個已經被訪問過
   if (node.right == null|| node.right == pnode){
    list.add(node.val);//直接訪問該節點,不在壓入其右孩子
    pnode = stack.pop();//記錄當前被訪問過的結點
    root = null;
   }else{
          //如果棧中壓入的結點的有右孩子,那麼壓入右孩子
    root = node.right;
   }
  }
        return list;  
 }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章