二叉树的遍历(java&python)

1.Binary Tree Preorder Traversal

java:

使用栈,时间复杂度O(n),空间复杂度O(n)
public static void preOrderRec(Node 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);
}
递归先序遍历,时间复杂度O(n),空间复杂度O(n) 
public static void preOrderRec(Node root){  
	if(root!=null){  
	   System.out.println(root.value);  
	   preOrderRec(root.left);  
	   preOrderRec(root.right);  
	}  
}

pthon:

# 递归
def preorderTraversal(root):
    if not root:
        return
    print(root.val)
    dfs(root.left)
    dfs(root.right)
# 栈
def preorderTraversal(root):
    stack = [root]
    while stack:
        p = stack.pop()
        print(p.val)
        if p.right:
            stack.append(p.right)
        if p.left:
            stack.append(p.left)

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

java:

使用栈,时间复杂度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;
	}
}
递归中序遍历,时间复杂度O(n),空间复杂度O(n)
public static void inOrderRec(Node root){  
    if(root!=null){  
        preOrderRec(root.left);  
        System.out.println(root.value);  
         preOrderRec(root.right);  
    }  
}  

python:

# 递归
def inorderTraversal(root):
    if not root:
        return
    dfs(root.left)
    print(root.val)
    dfs(root.right)
# 栈
def inorderTraversal(root):
    p = root
    stack = []
    while p or stack:
        if p:
            stack.append(p)
            p = p.left
        else:
            cur = stack.pop()
            print(cur.val)
            p = cur.right

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

步骤:

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

java:

    使用栈,时间复杂度O(n),空间复杂度O(n)
    /* p,正在访问的结点,q,刚刚访问过的结点 */
    public static void postOrderRec(Node root){  
		TreeNode p = root.left;
        Stack<TreeNode> s = new Stack<>();
        s.push(root)
		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);  
    }  
}  

python:

# 递归
def postorderTraversal(root):
    if not root:
        return
    dfs(root.left)
    dfs(root.right)
    print(root.val)
# 栈
def postorderTraversal(root):
    stack = [root]
    p = root.left
    while stack:
        while p:
            stack.append(p)
            p = p.left
        pre = None
        while stack:
            p = stack.pop()
            if p.right == pre:
                print(p.val)
                pre = p
            else:
                stack.append(p)
                p = p.right
                break

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值