二叉树遍历
前、中、后序遍历
前序遍历:
1.先输出当前节点
2.如果左子树不为空,则递归继续前序遍历
3.如果右子树不为空,则递归继续前序遍历
中序遍历:
1.如果左子树不为空,则递归继续中序遍历
2.再输出当前节点
3.如果右子树不为空,则递归继续中序遍历
后序遍历:
1.如果左子树不为空,则递归继续后序遍历
2.如果右子树不为空,则递归继续后序遍历
3.再输出当前节点
前序遍历
// 前序遍历
public void preOrder(HeroNode root){
if (root != null){
// 先根节点
System.out.println(root);
// 再左递归
preOrder(root.left);
// 再右递归
preOrder(root.right);
}
}
中序遍历
// 中序遍历
public void infixOrder(HeroNode root){
if (root != null){
// 先左递归
infixOrder(root.left);
// 再根节点
System.out.println(root);
// 再右递归
infixOrder(root.right);
}
}
后续遍历
// 后序遍历
public void postOrder(HeroNode root){
if (root != null){
// 先左递归
postOrder(root.left);
// 再右节点
postOrder(root.right);
// 再根节点
System.out.println(root);
}
}
测试
package com.jamin.binarytree;
public class TraverseDemo {
public static void main(String[] args) {
// 创建树
BinaryTree binaryTree = new BinaryTree();
// 创建节点
HeroNode root = new HeroNode(1, "Jamin1");
HeroNode node2 = new HeroNode(2, "Jamin2");
HeroNode node3 = new HeroNode(3, "Jamin3");
HeroNode node4 = new HeroNode(4, "Jamin4");
// 说明:这里手动创建节点,后面学习用递归的方式创建二叉树
binaryTree.setRoot(root);
root.setLeft(node2);
root.setRight(node3);
node3.setRight(node4);
// 前序遍历
System.out.println("----- 前序遍历 -----");
binaryTree.preOrder(binaryTree.root);
// 中序遍历
System.out.println("----- 中序遍历 -----");
binaryTree.infixOrder(binaryTree.root);
// 后序遍历
System.out.println("----- 后序遍历 -----");
binaryTree.postOrder(binaryTree.root);
}
}
// 定义二叉树
class BinaryTree{
public HeroNode root;
public void setRoot(HeroNode root) {
this.root = root;
}
// 前序遍历
public void preOrder(HeroNode root){
if (root != null){
// 先根节点
System.out.println(root);
// 再左递归
preOrder(root.left);
// 再右递归
preOrder(root.right);
}
}
// 中序遍历
public void infixOrder(HeroNode root){
if (root != null){
// 先左递归
infixOrder(root.left);
// 再根节点
System.out.println(root);
// 再右递归
infixOrder(root.right);
}
}
// 后序遍历
public void postOrder(HeroNode root){
if (root != null){
// 先左递归
postOrder(root.left);
// 再右节点
postOrder(root.right);
// 再根节点
System.out.println(root);
}
}
}
// 定义树节点
class HeroNode{
public int no;
public String name;
public HeroNode left;
public HeroNode right;
public HeroNode(int no, String name) {
this.no = no;
this.name = name;
}
public void setLeft(HeroNode left) {
this.left = left;
}
public void setRight(HeroNode right) {
this.right = right;
}
@Override
public String toString() {
return "HeroNode{" +
"no=" + no +
", name='" + name + '\'' +
'}';
}
}
输出:
----- 前序遍历 -----
TreeNode{no=1, name='Jamin1'}
TreeNode{no=2, name='Jamin2'}
TreeNode{no=3, name='Jamin3'}
TreeNode{no=4, name='Jamin4'}
----- 中序遍历 -----
TreeNode{no=2, name='Jamin2'}
TreeNode{no=1, name='Jamin1'}
TreeNode{no=3, name='Jamin3'}
TreeNode{no=4, name='Jamin4'}
----- 后序遍历 -----
TreeNode{no=2, name='Jamin2'}
TreeNode{no=4, name='Jamin4'}
TreeNode{no=3, name='Jamin3'}
TreeNode{no=1, name='Jamin1'}
前、中、后序查找
思路
前序查找:
1,先判断传入的根节点参数是否为null,如果为null,就返回null,结束查找
2.如果不为null:
i.先判断根节点是否是需要查找的节点,如果是就返回根节点并结束查找
ii.如果不是需要查找的节点,就进行左递归:将左递归的值用一个变量保存起来(用于判断是否需要提前结束查找)
iii.如果左递归返回的值不为null,则说明左递归已经找到该节点,所以返回该节点并结束查找
iv.如果左递归返回的值为null,则说明左递归没有找到该节点,所以需要进行右递归,并保存有递归的值
v.返回右递归的值、结束查找(这里不需要再对返回的值进行判空,因为右递归结束就代表查找结束了)
中序查找:
参照前序查找:
后序查找:
参照前序查找:
前序查找
// 前序遍历查找
public TreeNode preOrderSearch(TreeNode root,int no){
if (root == null){ // 如果根节点是Null,则返回Null
return null;
}
if (root.no == no){ // 前序:先判断根节点是否是查找节点
return root;
}
TreeNode resNode = null; // 用于存放查找结果
if (root.left != null){ // 左节点不为空时,进行左递归
resNode = preOrderSearch(root.left,no); // 存放递归结果,可能是TreeNode和null
}
if (resNode != null){ // 说明左递归已经找到节点:则可以结束查找
return resNode;
}
if (root.right != null){ // 右节点不为空时,进行右递归
resNode = preOrderSearch(root.right,no);// 存放递归结果,可能是TreeNode和null
}
// 这里不需要进行判断了,因为不管resNode的结果是什么,右递归结束时,就必须返回值。
// 左递归判断的原因是:如果左递归已经找到了,就可以提前结束查找了
return resNode;
}
中序查找
// 中序查找
public TreeNode infixOrderSearch(TreeNode root,int no){
if (root == null){
return null;
}
TreeNode resNode = null;
if (root.left != null){
resNode = infixOrderSearch(root.left, no);
}
if (resNode != null){
return resNode;
}
if (root.no == no){
return root;
}
if (root.right != null){
resNode = infixOrderSearch(root.right, no);
}
return resNode;
}
后序查找
// 后序查找
public TreeNode postOrderSearch(TreeNode root,int no){
if (root == null){
return null;
}
TreeNode resNode = null;
if (root.left != null){
resNode = postOrderSearch(root.left,no);
}
if (resNode != null){
return resNode;
}
if (root.right != null){
resNode = postOrderSearch(root.right, no);
}
if (root.no == no){
return root;
}
return resNode;
}
测试
package com.jamin.binarytree;
public class BinaryTreeSearchDemo {
public static void main(String[] args) {
// 创建树
BinaryTree1 binaryTree = new BinaryTree1();
// 创建节点
TreeNode root = new TreeNode(1, "Jamin1");
TreeNode node2 = new TreeNode(2, "Jamin2");
TreeNode node3 = new TreeNode(3, "Jamin3");
TreeNode node4 = new TreeNode(4, "Jamin4");
// 说明:这里手动创建节点,后面学习用递归的方式创建二叉树
root.setLeft(node2);
root.setRight(node3);
node3.setRight(node4);
binaryTree.setRoot(root);
// 进行前序查找
System.out.println("查找结果为: " + binaryTree.preOrderSearch(binaryTree.root,2));
// 进行中序查找
System.out.println("查找结果为: " + binaryTree.infixOrderSearch(binaryTree.root,3));
// 进行后序查找
System.out.println("查找结果为: " + binaryTree.postOrderSearch(binaryTree.root,4));
System.out.println("查找结果为: " + binaryTree.postOrderSearch(binaryTree.root,5));
}
}
class BinaryTree1{
public TreeNode root;
public void setRoot(TreeNode root) {
this.root = root;
}
// 前序遍历查找
public TreeNode preOrderSearch(TreeNode root,int no){
if (root == null){ // 如果根节点是Null,则返回Null
return null;
}
if (root.no == no){ // 前序:先判断根节点是否是查找节点
return root;
}
TreeNode resNode = null; // 用于存放查找结果
if (root.left != null){ // 左节点不为空时,进行左递归
resNode = preOrderSearch(root.left,no); // 存放递归结果,可能是TreeNode和null
}
if (resNode != null){ // 说明左递归已经找到节点:则可以结束查找
return resNode;
}
if (root.right != null){ // 右节点不为空时,进行右递归
resNode = preOrderSearch(root.right,no);// 存放递归结果,可能是TreeNode和null
}
// 这里不需要进行判断了,因为不管resNode的结果是什么,右递归结束时,就必须返回值。
// 左递归判断的原因是:如果左递归已经找到了,就可以提前结束查找了
return resNode;
}
// 中序查找
public TreeNode infixOrderSearch(TreeNode root,int no){
if (root == null){
return null;
}
TreeNode resNode = null;
if (root.left != null){
resNode = infixOrderSearch(root.left, no);
}
if (resNode != null){
return resNode;
}
if (root.no == no){
return root;
}
if (root.right != null){
resNode = infixOrderSearch(root.right, no);
}
return resNode;
}
// 后序查找
public TreeNode postOrderSearch(TreeNode root,int no){
if (root == null){
return null;
}
TreeNode resNode = null;
if (root.left != null){
resNode = postOrderSearch(root.left,no);
}
if (resNode != null){
return resNode;
}
if (root.right != null){
resNode = postOrderSearch(root.right, no);
}
if (root.no == no){
return root;
}
return resNode;
}
}
// 定义树节点
// 在同一个包下,在遍历那里定义了,所以这里不需要定义了
输出:
查找结果为: TreeNode{no=2, name='Jamin2'}
查找结果为: TreeNode{no=3, name='Jamin3'}
查找结果为: TreeNode{no=4, name='Jamin4'}
查找结果为: null