zoukankan      html  css  js  c++  java
  • 二叉树的遍历

    ·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);  
        }  
    }  
    

      

  • 相关阅读:
    Notes of Daily Scrum Meeting(12.18)
    Notes of Daily Scrum Meeting(12.17)
    Notes of Daily Scrum Meeting(12.16)
    Notes of Daily Scrum Meeting(12.8)
    Notes of Daily Scrum Meeting(12.5)
    Notes of Daily Scrum Meeting(12.3)
    Notes of Daily Scrum Meeting(11.12)
    Linux中profile、bashrc、bash_profile之间的区别和联系
    Linux GCC编译
    mysql 5.7.16 远程连接
  • 原文地址:https://www.cnblogs.com/rnanprince/p/11595380.html
Copyright © 2011-2022 走看看