• 二叉树的遍历


    ·1.Binary Tree Preorder Traversal

    使用栈,时间复杂度O(n),空间复杂度O(n)
    public List<Integer> preorderTraversal(TreeNode root) {
     ArrayList<Integer> result = new ArrayList<>();
     Stack<TreeNode> s = new Stack<>();
        if (root != null) s.push(root);
        while (!s.isEmpty()) {
            final TreeNode p = s.pop();
          result.add(p.val);
          if (p.right != null) s.push(p.right);
          if (p.left != null) s.push(p.left);
      }
      return result;
    }
    

      

    递归先序遍历,时间复杂度O(n),空间复杂度O(n) 
    public static void preOrderRec(Node root){  
      if(root!=null){  
         System.out.println(root.value);  
         preOrderRec(root.left);  
         preOrderRec(root.right);  
      }  
    }  
    

    Morris先序遍历,时间复杂度O(n),空间复杂度O(1)

    步骤:

    1.如果当前节点的左孩子为空,则输出当前节点并将其右孩子作为当前节点。

    2.如果当前节点的左孩子不为空,在当前节点的左子树中找到当前节点在中序遍历下的前驱节点。

    a) 如果前驱节点的右孩子为空,将它的右孩子设置为当前节点。输出当前节点(在这里输出,这是与中序遍历唯一一点不同)。当前节点更新为当前节点的左孩子。

    b) 如果前驱节点的右孩子为当前节点,将它的右孩子重新设为空。当前节点更新为当前节点的右孩子。

    3.重复以上1、2直到当前节点为空。

    public List<Integer> preorderTraversal(TreeNode root) {
    		ArrayList<Integer> result = new ArrayList<>();
    		TreeNode cur = root;
    		TreeNode prev = null;
    
    		while (cur != null) {
    			if (cur.left == null) {
    				result.add(cur.val);
    				prev = cur;
    				cur = cur.right;
    			} else {
    				/* 查找前驱 */
    				prev = cur.left;
    				while (prev.right != null && prev.right != cur) {
    					prev = prev.right;
    				}
    
    				if (prev.right == null) {	/* 还没线索化,则建立线索 */
    					result.add(cur.val); 	/* 仅这一行的位置与中序不同 */
    					prev.right = cur;
    					prev = cur;		/* cur刚刚被访问过 */
    					cur = cur.left;
    				} else {			/* 已经线索化,则访问节点,并删除线索 */
    					prev.right = null;
    					cur = cur.right;
    				}
    			}
    		}
    		return result;
    
    	}
    

     2.Binary Tree Inorder Traversal

    使用栈,时间复杂度O(n),空间复杂度O(n)
    public List<Integer> inorderTraversal(TreeNode root) {
        ArrayList<Integer> result = new ArrayList<>();
        Stack<TreeNode> s = new Stack<>();
    
        TreeNode pNode = root;
        while (!s.isEmpty() || pNode != null) {
    	  if (pNode != null) {
    		  s.push(pNode);
    		  pNode = pNode.left;
    	  } else {
    		  pNode = s.pop();
    		  result.add(pNode.val);
    		  pNode = pNode.right;
    	  }
        }
        return result;
    }
    

      

    递归中序遍历,时间复杂度O(n),空间复杂度O(n)
    public static void inOrderRec(Node root){  
        if(root!=null){  
            preOrderRec(root.left);  
            System.out.println(root.value);  
             preOrderRec(root.right);  
        }  
    }  
    

     使用栈,时间复杂度O(n),空间复杂度O(n)

    步骤:

    1.如果当前节点的左孩子为空,则输出当前节点并将其右孩子作为当前节点。

    2.如果当前节点的左孩子不为空,在当前节点的左子树中找到当前节点在中序遍历下的前驱节点。

    a) 如果前驱节点的右孩子为空,将它的右孩子设置为当前节点。当前节点更新为当前节点的左孩子。

    b) 如果前驱节点的右孩子为当前节点,将它的右孩子重新设为空(恢复树的形状)。输出当前节点。当前节点更新为当前节点的右孩子。

    3.重复以上1、2直到当前节点为空。

    public List<Integer> inorderTraversal1(TreeNode root) {
    		ArrayList<Integer> result = new ArrayList<>();
    		TreeNode cur = root;
    		TreeNode prev = null;
    
    		while (cur != null) {
    			if (cur.left == null) {
    				result.add(cur.val);
    				prev = cur;
    				cur = cur.right;
    			} else {
    				/* 查找前驱 */
    				prev = cur.left;
    				while (prev.right != null && prev.right != cur) {
    					prev = prev.right;
    				}
    
    				if (prev.right == null) {/* 还没线索化,则建立线索 */
    					prev.right = cur;
    					cur = cur.left;
    				} else {/* 已经线索化,则访问节点,并删除线索 */
    					result.add(cur.val);
    					prev.right = null;
    					prev = cur; /* cur刚刚被访问过 */
    					cur = cur.right;
    				}
    			}
    		}
    		return result;
    
    	}
    

    3.Binary Tree Postorder Traversal

     
        使用栈,时间复杂度O(n),空间复杂度O(n)
        /* p,正在访问的结点,q,刚刚访问过的结点 */
        public static void postOrderRec(Node root){  
    		TreeNode p = root;
    		TreeNode q = null;
    		while (!s.isEmpty()) {
    			while (p != null) {
    				s.push(p);
    				p = p.left;
    			}
    			q = null;
    			while (!s.isEmpty()) {
    				p = s.pop();
    				if (p.right == q) {
    					result.add(p.val);
    					q = p;
    				} else {
    					s.push(p);
    					p = p.right;
    					break;
    				}
    			}
    		}
        }
    
    递归后序遍历,时间复杂度O(n),空间复杂度O(n) 
    public static void postOrderRec(Node root){  
        if(root!=null){  
            preOrderRec(root.left);  
            preOrderRec(root.right);  
            System.out.println(root.value);  
        }  
    }  
    

      

  • 相关阅读:
    康拓展开
    P6032 选择客栈 加强版 递推
    0923考试T3 二进制,位运算
    0922考试T3 dfs序 lca 线段树 树上问题
    0921考试T2
    0922考试T1
    P3934 [Ynoi2016]炸脖龙I 树状数组 扩展欧拉定理
    0922考试T4 区间DP
    P6834 [Cnoi2020]梦原 树状数组 期望DP
    UVA1364 Knights of the Round Table Tarjan求点双联通分量+二分图染色
  • 原文地址:https://www.cnblogs.com/rnanprince/p/11595380.html
Copyright © 2020-2023  润新知