/**
* 二叉树定义
*/
public class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode(int x) { val = x; }
}
一、前序遍历
前序遍历二叉树比较简单,通过栈来保存节点,每次从栈中获得当前节点后保存本节点的子节点,如此循环直至栈为空。
/**
* 前序遍历二叉树
* @param root
* @return
*/
public List<Integer> preorderTraversal(TreeNode root) {
List<Integer> list = new ArrayList<>();
Stack<TreeNode> stack = new Stack<>();
if(root != null){
stack.push(root);
while(stack .size() != 0){
//获取当前节点
TreeNode node = stack.pop();
list.add(node.val);
//判断右节点是否为空,压栈
if(node.right != null){
stack.push(node.right);
}
//判断左节点是否为空,压栈
if(node.left != null){
stack.push(node.left);
}
}
}
return list;
}
二、中序遍历
/**
* 中序遍历二叉树
* @param root
* @return
*/
public List<Integer> inorderTraversal(TreeNode root) {
List<Integer> list = new ArrayList<>();
Stack<TreeNode> stack = new Stack<>();
while (root != null || !stack.empty()){
//循环遍历左子树直至为空
while (root != null){
stack.push(root);
root = root.left;
}
//获得最后一个节点
TreeNode node = stack.pop();
list.add(node.val);
//获取右节点
root = node.right;
}
return list;
}
三、后序遍历
后序遍历二叉树的难点在于,我们不知道右子树是否已经遍历了。因此需要增加一个lastVisit来判断是否已经遍历右子树。
/**
* 后序遍历二叉树
* @param root
* @return
*/
public List<Integer> postorderTraversal(TreeNode root) {
List<Integer> list = new ArrayList<>();
Stack<TreeNode> stack = new Stack<>();
TreeNode node = root;
TreeNode lastVisit = root;
while(node != null || !stack.empty()){
//遍历左子树直至末尾
while(node != null){
stack.push(node);
node = node.left;
}
//获得栈顶元素,这里不用pop是因为尚未判断右子树是否遍历
node = stack.peek();
//如果右子树已经遍历或为空就直接获取当前节点
if(node.right == null || lastVisit == node.right){
list.add(node.val);
stack.pop();
lastVisit = node;
node = null;
}else{
//右子树没有遍历,则遍历右子树
node = node.right;
}
}
return list;
}
四、层次遍历
层次遍历二叉树是通过队列完成。通过队列FIFO的特性,通过设置levelNum标志获得队列的大小从而获得每一层的节点个数,并由此获得每一层的循环次数。
/**
* 层次遍历二叉树
* @param root
* @return
*/
public List<List<Integer>> levelOrder(TreeNode root) {
Queue queue = new LinkedList();
List<List<Integer>> list = new ArrayList<>();
if(root != null){
//根节点作为第一层
queue.add(root);
while(!queue.isEmpty()){
//获得该层的节点数作为循环次数
int levelNum = queue.size();
List<Integer> level = new ArrayList<>();
for (int i = 0; i < levelNum; i++) {
TreeNode node = (TreeNode)queue.poll();
if(node.left != null){
//获得该节点的子树
queue.add(node.left);
}
if(node.right != null){
//同上
queue.add(node.right);
}
level.add(node.val);
}
list.add(level);
}
}
return list;
}