二叉树前序、中序、后序遍历(递归、非递归)

递归

package class10;

public class Code02_RecursiveTraversalBT {

	public static class Node {
		public int value;
		public Node left;
		public Node right;

		public Node(int v) {
			value = v;
		}
	}

	// 先序打印所有节点
	public static void pre(Node head) {
		if (head == null) {
			return;
		}
		System.out.println(head.value);
		pre(head.left);
		pre(head.right);
	}

	public static void in(Node head) {
		if (head == null) {
			return;
		}
		in(head.left);
		System.out.println(head.value);
		in(head.right);
	}

	public static void pos(Node head) {
		if (head == null) {
			return;
		}
		pos(head.left);
		pos(head.right);
		System.out.println(head.value);
	}

	public static void main(String[] args) {
		Node head = new Node(1);
		head.left = new Node(2);
		head.right = new Node(3);
		head.left.left = new Node(4);
		head.left.right = new Node(5);
		head.right.left = new Node(6);
		head.right.right = new Node(7);

		pre(head);
		System.out.println("========");
		in(head);
		System.out.println("========");
		pos(head);
		System.out.println("========");

	}
}

非递归

package class10;

import java.util.Stack;

public class Code03_UnRecursiveTraversalBT {

	public static class Node {
		public int value;
		public Node left;
		public Node right;

		public Node(int v) {
			value = v;
		}
	}

	public static void pre(Node head) {
		System.out.print("pre-order: ");
		if (head != null) {
			Stack<Node> stack = new Stack<Node>();
			stack.add(head);
			while (!stack.isEmpty()) {
				head = stack.pop();
				System.out.print(head.value + " ");
				if (head.right != null) {
					stack.push(head.right);
				}
				if (head.left != null) {
					stack.push(head.left);
				}
			}
		}
		System.out.println();
	}

	public static void in(Node cur) {
		System.out.print("in-order: ");
		if (cur != null) {
			Stack<Node> stack = new Stack<Node>();
			while (!stack.isEmpty() || cur != null) {
				if (cur != null) {
					stack.push(cur);
					cur = cur.left;
				} else {
					cur = stack.pop();
					System.out.print(cur.value + " ");
					cur = cur.right;
				}
			}
		}
		System.out.println();
	}

	public static void pos1(Node head) {
		System.out.print("pos-order: ");
		if (head != null) {
			Stack<Node> s1 = new Stack<Node>();
			Stack<Node> s2 = new Stack<Node>();
			s1.push(head);
			while (!s1.isEmpty()) {
				head = s1.pop(); // 头 右 左
				s2.push(head);
				if (head.left != null) {
					s1.push(head.left);
				}
				if (head.right != null) {
					s1.push(head.right);
				}
			}
			// 左 右 头
			while (!s2.isEmpty()) {
				System.out.print(s2.pop().value + " ");
			}
		}
		System.out.println();
	}

	public static void pos2(Node h) {
		System.out.print("pos-order: ");
		if (h != null) {
			Stack<Node> stack = new Stack<Node>();
			stack.push(h);
			Node c = null;
			while (!stack.isEmpty()) {
				c = stack.peek();
				if (c.left != null && h != c.left && h != c.right) {
					stack.push(c.left);
				} else if (c.right != null && h != c.right) {
					stack.push(c.right);
				} else {
					System.out.print(stack.pop().value + " ");
					h = c;
				}
			}
		}
		System.out.println();
	}

	public static void main(String[] args) {
		Node head = new Node(1);
		head.left = new Node(2);
		head.right = new Node(3);
		head.left.left = new Node(4);
		head.left.right = new Node(5);
		head.right.left = new Node(6);
		head.right.right = new Node(7);

		pre(head);
		System.out.println("========");
		in(head);
		System.out.println("========");
		pos1(head);
		System.out.println("========");
		pos2(head);
		System.out.println("========");
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 二叉树中序前序后序遍历算法分为递归非递归两种方法。 递归遍历算法: 1. 中序遍历:先遍历左子树,再访问根节点,最后遍历右子树。 2. 前序遍历:先访问根节点,再遍历左子树,最后遍历右子树。 3. 后序遍历:先遍历左子树,再遍历右子树,最后访问根节点。 非递归遍历算法: 1. 中序遍历:使用栈来模拟递归过程,先将根节点入栈,然后将左子树的所有节点入栈,直到遇到叶子节点,然后出栈并访问该节点,再将右子树的所有节点入栈,重复上述过程。 2. 前序遍历:使用栈来模拟递归过程,先将根节点入栈,然后出栈并访问该节点,再将右子树入栈,最后将左子树入栈,重复上述过程。 3. 后序遍历:使用栈来模拟递归过程,先将根节点入栈,然后将左子树的所有节点入栈,直到遇到叶子节点,然后将右子树的所有节点入栈,最后出栈并访问该节点,重复上述过程。需要使用一个辅助栈来记录已经访问过的节点。 ### 回答2: 二叉树中序前序后序遍历是树的三种基本遍历方法,他们都有递归非递归两种算法。 1. 中序遍历 中序遍历是先访问左子树,再访问根节点,最后访问右子树。递归遍历可以先递归访问左子树,然后输出根节点,继续递归访问右子树。非递归遍历可以用栈进行模拟,从根节点开始,先访问左子树,遇到左子树都入栈,然后输出根节点,最后遍历右子树。 2. 前序遍历 前序遍历是先访问根节点,再访问左子树,最后访问右子树。递归遍历可以先输出根节点,然后递归访问左子树和右子树。非递归遍历可以用栈进行模拟,从根节点开始,先输出根节点,然后将右子树入栈,最后遍历左子树。 3. 后序遍历 后序遍历是先访问左子树,再访问右子树,最后访问根节点。递归遍历可以先递归访问左子树和右子树,最后输出根节点。非递归遍历可以用栈进行模拟,在遍历每个节点的时候都要记录下该节点是否已经被访问过了,当左右子树都被访问过的时候,再输出根节点。 总之,递归遍历的代码比较简单,但是会使用到函数调用栈,容易导致栈溢出,所以针对比较大的二叉树,我们通常使用非递归遍历。非递归遍历可以使用栈来模拟递归过程,但是需要注意栈空的时候需要退出循环。 ### 回答3: 二叉树遍历是指以某种顺序依次访问二叉树中所有结点,是二叉树最常用的操作之一。常见的遍历方式有中序遍历、前序遍历和后序遍历。这三种遍历方式都可以采用递归非递归算法实现。 1. 中序遍历 中序遍历的顺序是左孩子-根节点-右孩子。递归实现中序遍历: ``` void inorder(TreeNode* root) { if (root == nullptr) return; inorder(root->left); visit(root); inorder(root->right); } ``` 非递归实现中序遍历: ``` vector<int> inorderTraversal(TreeNode* root) { vector<int> res; stack<TreeNode*> s; TreeNode* cur = root; while (cur || !s.empty()) { while (cur) { s.push(cur); cur = cur->left; } cur = s.top(); s.pop(); res.push_back(cur->val); cur = cur->right; } return res; } ``` 2. 前序遍历 前序遍历的顺序是根节点-左孩子-右孩子。递归实现前序遍历: ``` void preorder(TreeNode* root) { if (root == nullptr) return; visit(root); preorder(root->left); preorder(root->right); } ``` 非递归实现前序遍历: ``` vector<int> preorderTraversal(TreeNode* root) { vector<int> res; if (root == nullptr) return res; stack<TreeNode*> s; s.push(root); while (!s.empty()) { TreeNode* tmp = s.top(); s.pop(); res.push_back(tmp->val); if (tmp->right) s.push(tmp->right); if (tmp->left) s.push(tmp->left); } return res; } ``` 3. 后序遍历 后序遍历的顺序是左孩子-右孩子-根节点。递归实现后序遍历: ``` void postorder(TreeNode* root) { if (root == nullptr) return; postorder(root->left); postorder(root->right); visit(root); } ``` 非递归实现后序遍历: ``` // 双栈法 vector<int> postorderTraversal(TreeNode* root) { vector<int> res; if (root == nullptr) return res; stack<TreeNode*> s1, s2; s1.push(root); while (!s1.empty()) { TreeNode* tmp = s1.top(); s1.pop(); s2.push(tmp); if (tmp->left) s1.push(tmp->left); if (tmp->right) s1.push(tmp->right); } while (!s2.empty()) { res.push_back(s2.top()->val); s2.pop(); } return res; } ``` ``` // 单栈法 vector<int> postorderTraversal(TreeNode* root) { vector<int> res; if (root == nullptr) return res; stack<TreeNode*> s; TreeNode* cur = root; TreeNode* last = nullptr; while (cur || !s.empty()) { while (cur) { s.push(cur); cur = cur->left; } cur = s.top(); if (cur->right == nullptr || cur->right == last) { res.push_back(cur->val); s.pop(); last = cur; cur = nullptr; } else { cur = cur->right; } } return res; } ``` 非递归的实现需要用到栈,代码实现可能有些繁琐,但是值得熟练掌握。在实际编码中,也可使用Morris遍历来实现二叉树遍历并节省空间。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值