二叉树的遍历
先序遍历
所有父节点先于左右子树的顺序,父亲 -> 左子树(递归) -> 右子树(递归)
后续遍历
所有父节点后于左右子树的顺序, 左子树(递归) -> 右子树(递归) -> 父亲
中序遍历
父节点的在左右子树的中间访问,左子树(递归)-> 父亲 -> 右子树(递归)
层序遍历
借助一个双端队列实现,比如有如下的二叉树
将根节点加入队列
不断地取出队列中第一个元素加入list, 并将当前节点的的两个孩子加入队列 ,
循环直到队列为空,则遍历结束
最终遍历结果为list, 工具双端队列queue:
list : | 1 | 12 | 123 | 1234 | 12345 | 123456 | 1234567 | 12345678 | 123456789 | |
---|---|---|---|---|---|---|---|---|---|---|
queue: | 1 | 23 | 345 | 4567 | 56789 | 6789 | 789 | 89 | 9 |
代码如下
package com.susq.algorithm.tree;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.List;
import java.util.Queue;
/**
* @author susq
* @since 2017-12-14-14:56
*/
public class BinTree<E> {
private TreeNode root;
public BinTree() {
this.root = new TreeNode();
}
public BinTree(E data) {
this.root = new TreeNode(data);
}
/**
* 为指定节点添加新节点
*
* @param parent 父节点
* @param data 新的数据
* @param isLeft 是否为左孩子
* @return 新的节点
*/
public TreeNode addNode(TreeNode parent, E data, boolean isLeft) {
if (parent == null) {
throw new RuntimeException("节点为null, 无法添加子节点");
}
if (isLeft && parent.left != null) {
throw new RuntimeException(parent + "已经有左子节点,无法继续添加");
}
if (!isLeft && parent.right != null) {
throw new RuntimeException(parent + "已经有右子节点,无法继续添加");
}
TreeNode newNode = new TreeNode(data);
if (isLeft) {
parent.left = newNode;
} else {
parent.right = newNode;
}
newNode.parent = parent;
return newNode;
}
public boolean empty() {
return root.data == null;
}
public TreeNode getRoot() {
if (empty()) {
throw new RuntimeException("树为空");
}
return root;
}
public E parent(TreeNode node) {
if (node == null) {
throw new RuntimeException("节点为空,没有父节点");
}
return (E) node.parent.data;
}
public E leftChild(TreeNode parent) {
if (parent == null) {
throw new RuntimeException("节点为空,没有孩子");
}
return parent.left == null ? null : (E) parent.left;
}
public E rightChild(TreeNode parent) {
if (parent == null) {
throw new RuntimeException("节点为空,没有孩子");
}
return parent.right == null ? null : (E) parent.right;
}
public int deep() {
return deep(root);
}
private int deep(TreeNode node) {
if (node == null) {
return 0;
}
if (node.left == null && node.right == null) {
return 1;
} else {
int leftDeep = deep(node.left);
int rightDeep = deep(node.right);
int max = leftDeep > rightDeep ? leftDeep : rightDeep;
return max + 1;
}
}
/**
* 实现先序遍历
*
* @return
*/
public List<TreeNode> preIterator() {
return preIterator(root);
}
private List<TreeNode> preIterator(TreeNode node) {
List<TreeNode> list = new ArrayList<>();
list.add(root);
// 递归处理左子树
if (node.left != null) {
list.addAll(preIterator(node.left));
}
// 递归处理右子树
if (node.right != null) {
list.addAll(preIterator(node.right));
}
return list;
}
/**
* 实现中序遍历
*
* @return
*/
public List<TreeNode> inIterator() {
return inIterator(root);
}
private List<TreeNode> inIterator(TreeNode node) {
List<TreeNode> list = new ArrayList<>();
if (node.left != null) {
list.addAll(inIterator(node.left));
}
list.add(root);
if (node.right != null) {
list.addAll(inIterator(node.right));
}
return list;
}
/**
* 实现后续遍历
*
* @return
*/
public List<TreeNode> psotIterator() {
return postIterator(root);
}
private List<TreeNode> postIterator(TreeNode node) {
List<TreeNode> list = new ArrayList<>();
if (node.left != null) {
list.addAll(postIterator(node.left));
}
if (node.right != null) {
list.addAll(postIterator(node.right));
}
list.add(root);
return list;
}
/**
* 实现广度优先遍历,又称为按层遍历
* 借助一个双端队列
*
* @return
*/
public List<TreeNode> breadthFirst() {
Queue<TreeNode> queue = new ArrayDeque<>(); //ArrayDeque数双端队列实现类
List<TreeNode> list = new ArrayList<>();
if (root != null) {
queue.offer(root); // offer:添加一个元素并返回true,如果队列已满,则返回false
}
// while 循环中,移除队列的第一个节点,并且将这个节点左子节点、右子节点加入队列,
// 每次取出队列中元素的时候,把它的所有孩子加入队列末尾,在二叉树中就是父节点遍历过后,把下层的节点加入队列。
while (!queue.isEmpty()) {
list.add(queue.peek()); // peek:返回队列头部的元素,如果队列为空,则返回null
TreeNode p = queue.poll(); //poll:移除并返问队列头部的元素, 如果队列为空,则返回null
if (p.left != null) {
queue.offer(p.left);
}
if (p.right != null) {
queue.offer(p.right);
}
}
return list;
}
/**
* 树的节点
*/
public static class TreeNode {
Object data;
TreeNode left;
TreeNode right;
TreeNode parent;
public TreeNode() {
}
public TreeNode(Object data) {
this.data = data;
}
public TreeNode(Object data, TreeNode left, TreeNode right, TreeNode parent) {
this.data = data;
this.left = left;
this.right = right;
this.parent = parent;
}
}
}