二叉树的遍历
二叉树的遍历常分先序遍历、中序遍历、后序遍历
- 先序遍历:先访问根节点,再访问左子节点,最后访问右子节点
- 中序遍历:先访问左子节点,再访问跟节点,最后访问右子节点
- 后序遍历:先访问左子节点,再访问右子节点,最好访问根节点
实现的逻辑分为递归、非递归的逻辑;
#TreeNode结构
public class TreeNode {
public int val;
public TreeNode left;
public TreeNode right;
public TreeNode(int x) {
val = x;
}
}
递归实现
public void visit(TreeNode node){
System.out.print(node.val+" ");
}
/**
* 递归先序遍历
**/
public void preOrderRecursion(TreeNode node){
if(node==null) //如果结点为空则返回
return;
visit(node);//访问根节点
preOrderRecursion(node.left);//访问左孩子
preOrderRecursion(node.right);//访问右孩子
}
/**
* 递归中序遍历
**/
public void preOrderRecursion(TreeNode node){
if(node==null) //如果结点为空则返回
return;
preOrderRecursion(node.left);//访问左孩子
visit(node);//访问根节点
preOrderRecursion(node.right);//访问右孩子
}
/**
* 递归后序遍历
**/
public void preOrderRecursion(TreeNode node){
if(node==null) //如果结点为空则返回
return;
preOrderRecursion(node.left);//访问左孩子
preOrderRecursion(node.right);//访问右孩子
visit(node);//访问根节点
}
非递归实现:
- 先序遍历
- 假设cur=head,将cur入栈
- 不断从栈中弹出栈顶节点,然后把右子节点和左子节点放入栈中
(因为先访问左子节点,栈为先进后出的数据结构,所以先放左子节点) - 当栈不为空,不断重复上一步骤
public List<Integer> preorderTraversal(TreeNode node) {
List<Integer> rt = new ArrayList<>();
Stack<TreeNode> stack = new Stack<>();
if (node == null) {
return rt;
}
stack.push(node);
while (!stack.empty()) {
TreeNode curNode = stack.pop();
rt.add(curNode.val);
if (curNode.right != null) {
stack.push(curNode.right);
}
if (curNode.left != null) {
stack.push(curNode.left);
}
}
return rt;
}
- 中序遍历
- 初始化cur=head
- 将cur入栈,不断将cur=cur.left(不断取左子节点),重复当前过程
- 如果cur为空,则已经访问到“最左“节点,出栈并打印当前节点的值,将其右子节点赋值给cur,重复上一步
public List<Integer> inorderTraversal(TreeNode node) {
List<Integer> rt = new ArrayList<>();
Stack<TreeNode> stack = new Stack<>();
if (node == null) {
return rt;
}
while (!stack.empty() || node != null) {
if (node != null) {
stack.push(node);
node = node.left;
} else {
node = stack.pop();
rt.add(node.val);
node = node.right;
}
}
return rt;
}
- 后序遍历
- 申请两个栈s1,s2,将头节点压入s1
- 从s1中弹出节点cur依次将cur的左孩子右孩子压入s1,同时将cur压入栈s2中
- 最后s2的栈即为访问顺序,不断弹出打印即可
public List<Integer> postorderTraversal(TreeNode root) {
List<Integer> rt = new ArrayList<>();
Stack<TreeNode> stack1 = new Stack<>();
Stack<TreeNode> stack2 = new Stack<>();
if (root == null){
return rt;
}
stack1.push(root);
while (!stack1.empty()){
TreeNode node = stack1.pop();
stack2.push(node);
if (node.left != null){
stack1.push(node.left);
}
if (node.right != null){
stack1.push(node.right);
}
}
while (!stack2.empty()){
rt.add(stack2.pop().val);
}
return rt;
}