目录
遍历二叉树
前序遍历(DLR,根左右)
(1)访问根结点。
(2)先序遍历根结点的左子树。
(3)先序遍历根结点的右子树。
中序遍历(LDR,左根右)
(1)先序遍历根结点的左子树。
(2)访问根结点。
(3)先序遍历根结点的右子树。
后序遍历(LRD,左右根)
(1)先序遍历根结点的左子树。
(2)先序遍历根结点的右子树。
(3)访问根结点。
层次遍历
从根结点开始,逐层自上而下遍历。当一层结点访问完后接着访问下一层,先遇到的结点先访问。
(1)将根结点入队,从对头取出一个元素,每取一个元素执行(2)。
(2)访问该元素所指结点。
(3)若该元素所指结点的左、右孩子结点非空,则将该元素所指结点的左孩子指针和右孩子指针依次入队。
(4)重复步骤(3),直到队空为止。
广度优先
深度优先
恢复二叉树
前序+中序
步骤:
(1)由前序序列获知根结点,然后根据中序序列确定左、右子树。
(2)由确定的左、右子树根据前序序列分别找出左、右子树的根结点,并把左、右子树的根结点连接到父结点。
(3)分别对左、右子树实行步骤(1)和(2),直到子树只剩下1个结点或2个结点或空为止。
前序:A C B R S E D F M L K
中序:R B S C E A F D L K M
1、 前序:A C B R S E D F M L K
根 左子树 右子树
中序:R B S C E A F D L K M
左子树 根 右子树
2、 前序:C B R S E 前序:D F M L K
根 左子树 右子树 根 左子树 右子树
中序:R B S C E 中序:F D L K M
左子树 根 右子树 左子树 根 右子树
3、......
后序+中序
步骤:
(1)由后序序列获知根结点,然后根据中序序列确定左、右子树。
(2)由确定的左、右子树根据后序序列分别找出左、右子树的根结点,并把左、右子树的根结点连接到父结点。
(3)分别对左、右子树实行步骤(1)和(2),直到子树只剩下1个结点或2个结点或空为止。
中序:C B E D A G H F J I
后续:C E D B H G J I F A
1、 后序:C E D B H G J I F A
左子树 右子树 根
中序:C B E D A G H F J I
左子树 根 右子树
2、 后序:C E D B 后序: H G J I F
左子树 右子树 根 左子树 右子树 根
中序:C B E D 中序:G H F J I
左子树 根 右子树 左子树 根 右子树
3、......
二叉树遍历代码实现
import java.util.ArrayDeque;
import java.util.Arrays;
import java.util.LinkedList;
//树遍历
public class BinaryTree {
//一、声明节点
public static class TreeNode{
public int val;
public TreeNode lchild;
public TreeNode rchild;
public TreeNode(int x){this.val=x;}
}
//二、构造二叉树 递归构造
public static TreeNode createBinaryTree(LinkedList<Integer> list) {
TreeNode node = null;
//出口
if(list.isEmpty()) return null;
//创建节点
Integer val = list.pollFirst();
//Integer val = list.removeFirst();
//递归构造
if(val!=null) {
node = new TreeNode(val);
node.lchild = createBinaryTree(list);
node.rchild = createBinaryTree(list);
}
return node;
}
//三、二叉树遍历
//1、先序遍历 递归
public static void preOrderTraversal(TreeNode node) {
//出口
if(node==null) return;
//输出当前节点
System.out.print(node.val + " ");
//继续遍历
preOrderTraversal(node.lchild);
preOrderTraversal(node.rchild);
}
//2、中序遍历 递归
public static void midOrderTraversal(TreeNode node) {
//出口
if(node==null) return;
//遍历
midOrderTraversal(node.lchild);
System.out.print(node.val+" "); // 输出当前节点
midOrderTraversal(node.rchild);
}
//3、后序遍历 递归
public static void postOrderTraversal(TreeNode node) {
//出口
if(node==null) return;
//遍历
postOrderTraversal(node.lchild);
postOrderTraversal(node.rchild);
//输出当前节点
System.out.print(node.val+" ");
}
//4、层次遍历 队列实现
public static void levelOrderTraversal(TreeNode root) {
//队列每次存储每一层的节点
ArrayDeque<TreeNode> deque = new ArrayDeque<>();
deque.addLast(root); //第一层的节点(根节点)
//最终结果
LinkedList<Integer> res = new LinkedList<Integer>();
//遍历 逐层访问
while (!deque.isEmpty()) {
int num = deque.size();//队列大小(当前层的节点数量)
//保存每一层的所有节点(每一层的结果)
//LinkedList<Integer> subList = new LinkedList<Integer>();
//当前层
for (int i = 0; i < num; i++) {
TreeNode node = deque.removeFirst();//当前层的当前节点
//当前层的当前节点的左右子节点(下一层的节点)
if (node.lchild != null) deque.addLast(node.lchild);//下一层的节点
if (node.rchild != null) deque.addLast(node.rchild);//下一层的节点
//保存当前层的当前节点(保存结果)
//subList.add(node.val);
res.add(node.val);
}
//输出(可以获取每一层的结果)
//System.out.print(subList);
}
System.out.print(res);
}
//5、广度优先遍历 队列实现
public static void breadthFirstSearch(TreeNode node) {
if(node==null)return;
//队列
LinkedList<TreeNode> queue = new LinkedList<>();
queue.add(node);//将根节点存放进队列中
//遍历
while(!queue.isEmpty()){//只要队列不为空,也就是说没有对树遍历完成
//当前节点
TreeNode cur = queue.removeFirst();
//输出
System.out.print(cur.val+" ");
//获取当前节点的子节点,将子节点存放进队列
if(cur.lchild!=null)
queue.add(cur.lchild);
if(cur.rchild!=null)
queue.add(cur.rchild);
}
}
//6、深度优先遍历 栈实现
public static void depthFirstSearch(TreeNode node) {
if(node==null) return;
//遍历左子节点
if (node.lchild != null)//先对左节点进行深度遍历
depthFirstSearch(node.lchild);
//输出当前节点的值,直到左节点为Null
System.out.print(node.val+" ");
//遍历右子节点
if (node.rchild != null)
depthFirstSearch(node.rchild);
//最后回溯返回到父节点
}
public static void main(String[] args) {
//原始节点数据
LinkedList<Integer> list = new LinkedList<>(Arrays.asList(new Integer[]{1,2,3,null,null,4,5,null,7,null,null,6,null,null}));
//构建二叉树
TreeNode root = createBinaryTree(list);
//遍历二叉树
System.out.println("1、前序遍历");
preOrderTraversal(root);
System.out.println("\n2、中序遍历");
postOrderTraversal(root);
System.out.println("\n3、后序遍历");
midOrderTraversal(root);
System.out.println("\n4、层次遍历");
levelOrderTraversal(root);
System.out.println("\n5、广度优先遍历");
breadthFirstSearch(root);
System.out.println("\n6、深度优先遍历");
depthFirstSearch(root);
}
}