先序遍历
面小米算法岗的时候写过一次,当时用的C,现在用Java写一下。
思路:循环栈中的元素,出栈一个节点(第一次出的是根节点),输出data,如果有左孩子的话,左孩子进栈;有孩子同理。
用栈来实现,这里用的是Stack。
构造一个栈,根节点入栈。
循环整个栈,出栈,并输出。(pop)
判断有没有右孩子,有的话入栈。
判断有没有左孩子,有的话入栈。
注意对比和层次遍历的区别:
1. 层次遍历用的是队列,且层次遍历是左孩子先入队,再是右孩子入队。
2. 先序遍历用的是栈,且先序遍历是右孩子先入栈,再是左孩子入栈。
private class Node{
int data;
Node lc;
Node rc;
public Node(int data){
this.data = data;
}
}
public void preOrder(Node root){
if(root == null){
System.out.println("空树");
}
Node temp = root;
Stack<Node> s = new Stack<Node>();
s.push(root);
while(!s.empty()){
Node p = s.pop();
System.out.print(p.data+" ");
if(p.lc != null){
s.push(p.rc);
}
if(p.rc != null){
s.push(p.lc);
}
}
}
层次遍历
二叉树的层次遍历,层次遍历就相当于一层一层的遍历,先是根节点,再是根节点的左孩子,右孩子。再试左孩子,左孩子的左孩子...
可以用队列来实现,这里用的是LinkedList,因为LinkedList可以轻松实现对列和栈的操作。
构造一个队列,根节点入队。
循环整个队列,出队,并输出。(这里出队可以用pop,也可以用poll)
判断有没有左孩子,有的话入队。
判断有没有右孩子,有的话入队。
package com.hisen.code;
import java.util.LinkedList;
public class LevelOrder {
public static class TreeNode {
public void setLeft(TreeNode left) {
this.left = left;
}
public void setRight(TreeNode right) {
this.right = right;
}
public TreeNode(int data){
this.data = data;
}
public int data;
public TreeNode left;
public TreeNode right;
}
public void levelIterator(TreeNode tree){
LinkedList<TreeNode> queqe = new LinkedList<TreeNode>();
if(tree == null) return ;
queqe.add(tree);
while( !queqe.isEmpty() ){
TreeNode t = queqe.pop();
System.out.println(t.data +" ");
if(t.left != null){
queqe.add(t.left);
}
if(t.right != null){
queqe.add(t.right);
}
}
}
public static void main(String[] args) {
TreeNode b1 = new TreeNode(1);
TreeNode b2 = new TreeNode(2);
TreeNode b3 = new TreeNode(3);
TreeNode b4 = new TreeNode(4);
TreeNode b5 = new TreeNode(5);
TreeNode b6 = new TreeNode(6);
TreeNode b7 = new TreeNode(7);
b1.setLeft(b2);
b1.setRight(b3);
b2.setLeft(b4);
b2.setRight(b5);
b3.setLeft(b6);
b3.setRight(b7);
LevelOrder levelOrder = new LevelOrder();
levelOrder.levelIterator(b1);
}
}
// 输出如下
1
2
3
4
5
6
7