Java 二叉树遍历相关

算法与数据结构 专栏收录该内容
5 篇文章 0 订阅

Java 二叉树遍历相关


package cn.sjtu.practice.test3;


import java.util.LinkedList;
import java.util.Queue;
import java.util.Stack;


public class Solution34 {


/**
* 求二叉树中两个节点的最低公共祖先节点 递归解法: (1)如果两个节点分别在根节点的左子树和右子树,则返回根节点
* (2)如果两个节点都在左子树,则递归处理左子树;如果两个节点都在右子树,则递归处理右子树
*/
static TreeNode LCA3(TreeNode root, TreeNode p, TreeNode q) {
if (root == null || p == null || q == null) {
return null;
}
if (root == p || root == q) {
return root;// 返回当前节点
}
TreeNode left = LCA3(root.left, p, q);
TreeNode right = LCA3(root.right, p, q);
// p和q分别在两边,则返回当前节点
if (left != null && right != null) {
return root;
}
return left == null ? right : left;
}


/**
* 求二叉查找树中两个节点的最低公共祖先节点 针对二叉查找树的特殊解法
* @param root
* @param p
* @param q
* @return
*/
static TreeNode LCA(TreeNode root, TreeNode p, TreeNode q) {
if (root == null || p == null || q == null) {
return null;
}
if (root.val > p.val && root.val > q.val) {
return LCA(root.left, p, q);
} else if (root.val < p.val && root.val < q.val) {
return LCA(root.right, p, q);
} else {
return root;
}


}


public static void main(String[] args) {
TreeNode t1 = new TreeNode(5);
TreeNode t2 = new TreeNode(3);
TreeNode t3 = new TreeNode(7);
TreeNode t4 = new TreeNode(1);
TreeNode t5 = new TreeNode(4);
TreeNode t6 = new TreeNode(9);


t1.left = t2;
t1.right = t3;
t2.left = t4;
t2.right = t5;
t3.right = t6;


// TreeNode lca = LCA3(t1, t4, t5);


// System.out.println("公共祖先:" + lca.val);
// preOrderTraverse(t1);
// System.out.println();
inOrderTraverse2(t1);
System.out.println();
// postOrderTraverse(t1);
}


/**
* 二叉树按层次输出

* @param root
*/
public static void levelTraversal(TreeNode root) {
if (root == null) {
return;
}
Queue<TreeNode> queue = new LinkedList<TreeNode>();
queue.add(root);


while (!queue.isEmpty()) {
TreeNode cur = queue.remove();
System.out.print(cur.val + " ");
if (cur.left != null) {
queue.add(cur.left);
}
if (cur.right != null) {
queue.add(cur.right);
}
}
}

/**
* 前序遍历2
* 迭代解法:用一个辅助stack,总是把右孩子放进栈
* @param root
*/
public static void preorderTraversal(TreeNode root) {
if (root == null) {
return;
}


Stack<TreeNode> stack = new Stack<TreeNode>(); // 辅助stack
stack.push(root);


while (!stack.isEmpty()) {
TreeNode cur = stack.pop(); // 出栈栈顶元素
System.out.print(cur.val + " ");
// 关键点:要先压入右孩子,再压入左孩子,这样在出栈时会先打印左孩子再打印右孩子
if (cur.right != null) {
stack.push(cur.right);
}
if (cur.left != null) {
stack.push(cur.left);
}
}
}


/**
* 中序遍历2
* 迭代解法:用一个辅助stack
* @param root
*/
public static void inOrderTraverse2(TreeNode root) {
if (root == null)
return;
TreeNode cur = root;
Stack<TreeNode> stack = new Stack<>();
while (cur != null || !stack.isEmpty()) {
if (cur != null) {
stack.push(cur);
cur = cur.left;
} else {
cur = stack.pop();
System.out.print(cur.val + " ");
cur = cur.right;
}


}
System.out.println();
}


/**
* 后序遍历2
* 迭代解法:用两个个辅助stack
* @param root
*/
public static void postOrderTraverse2(TreeNode root) {
if (root == null)
return;


Stack<TreeNode> stack = new Stack<>();
Stack<TreeNode> output = new Stack<TreeNode>();
stack.push(root);
while (!stack.isEmpty()) {
TreeNode cur = stack.pop();
output.push(cur);
if (cur.left != null) {
stack.push(cur.left);
}
if (cur.right != null) {
stack.push(cur.right);
}
}
while (!output.isEmpty()) {
TreeNode temp = output.pop();
System.out.print(temp.val + " ");
}
System.out.println();
}


public static void show(TreeNode head) {
while (head != null) {
System.out.print(head.val);
head = head.right;
}
System.out.println();
}


/**
* 先序遍历 这三种不同的遍历结构都是一样的,只是先后顺序不一样而已

* @param node
*/
public static void preOrderTraverse(TreeNode node) {
if (node == null)
return;
System.out.print(node.val + " ");
preOrderTraverse(node.left);
preOrderTraverse(node.right);
}


/**
* 中序遍历 这三种不同的遍历结构都是一样的,只是先后顺序不一样而已

* @param node
*            遍历的节点
*/
public static void inOrderTraverse(TreeNode node) {
if (node == null)
return;
inOrderTraverse(node.left);
System.out.print(node.val + " ");
inOrderTraverse(node.right);
}


/**
* 后序遍历 这三种不同的遍历结构都是一样的,只是先后顺序不一样而已

* @param node
*/
public static void postOrderTraverse(TreeNode node) {
if (node == null)
return;
postOrderTraverse(node.left);
postOrderTraverse(node.right);
System.out.print(node.val + " ");
}
}

  • 1
    点赞
  • 0
    评论
  • 0
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

©️2021 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值