在面试的算法题中,二叉树基本属于基础的基础类型了,必须掌握,可以说最好背下来。
然后写法上来说,遍历一般就迭代和递归两种写法,下面我会帖代码
前序遍历
递归写法:
List<Integer> ans;
public List<Integer> preorderTraversal(TreeNode root) {
ans = new ArrayList<>();
dfs(root);
return ans;
}
public void dfs(TreeNode root){
if (root==null){
return;
}
ans.add(root.val);
dfs(root.left);
dfs(root.right);
}
迭代写法1:
public List<Integer> preorderTraversal(TreeNode root){
List<Integer> ans = new ArrayList<>();
if (root==null){
return ans;
}
//这种相当于本能的模拟前序的情形
Deque<TreeNode> stack = new LinkedList<>();
while (!stack.isEmpty()||root!=null){
while (root!=null){
ans.add(root.val);
stack.push(root);
root=root.left;
}
root=stack.pop();
root=root.right;
}
return ans;
}
迭代写法2:
//直接使用原始的思想来模拟前序的迭代法
//事实上通过这种不太“正经”的写法,我对栈有了更深刻的认识
public List<Integer> preorderTraversal(TreeNode root){
Deque<TreeNode> stack = new LinkedList<>();
List<Integer> ans = new ArrayList<>();
stack.push(root);
while (!stack.isEmpty()){
TreeNode now = stack.pop();
ans.add(now.val);
if (now.right!=null){
stack.push(now.right);
}
if (now.left!=null){
stack.push(now.left);
}
}
return ans;
}
中序遍历
递归写法:
static List<Integer> ans;
public List<Integer> inorderTraversal(TreeNode root) {
ans = new ArrayList<>();
dfs(root);
return ans;
}
public static void dfs(TreeNode root){
if (root==null){
return;
}
dfs(root.left);
ans.add(root.val);
dfs(root.right);
}
迭代写法:
//用栈来实现迭代
public List<Integer> inorderTraversal(TreeNode root){
List<Integer> ans = new ArrayList<>();
Deque<TreeNode> stack=new LinkedList<>();
TreeNode node=root;
while (!stack.isEmpty()||node!=null){
while (node!=null){
stack.push(node);
node=node.left;
}
node=stack.pop();
ans.add(node.val);
node=node.right;
}
return ans;
}
后序遍历
递归写法:
static List<Integer> anslist;
public List<Integer> postorderTraversal(TreeNode root) {
anslist=new ArrayList<>();
if (root==null){
return anslist;
}
dfs(root);
return anslist;
}
public static void dfs(TreeNode root){
if (root==null){
return;
}
dfs(root.left);
dfs(root.right);
anslist.add(root.val);
}
迭代写法1:
//这个是官解的迭代解法
public List<Integer> postorderTraversal(TreeNode root) {
List<Integer> res = new ArrayList<Integer>();
if (root == null) {
return res;
}
Deque<TreeNode> stack = new LinkedList<TreeNode>();
TreeNode prev = null;
while (root != null || !stack.isEmpty()) {
while (root != null) {
stack.push(root);
root = root.left;
}
root = stack.pop();
if (root.right == null || root.right == prev) {
res.add(root.val);
prev = root;
root = null;
} else {
stack.push(root);
root = root.right;
}
}
return res;
}
迭代写法2(相当于前序遍历迭代写法2的异构版本,可以想象前序“倒”过来)
//迭代的奇怪写法:即前序的异构版本
//这种写法非常骚,addfirst,左右互换位置
public List<Integer> postorderTraversal(TreeNode root) {
Deque<TreeNode> stack = new LinkedList<>();
LinkedList<Integer> ans = new LinkedList<>();
if (null == root) return ans;
stack.addFirst(root);
while(!stack.isEmpty()) {
TreeNode node = stack.removeFirst();
ans.addFirst(node.val);
if (null != node.left) {
stack.addFirst(node.left);
}
if (null != node.right) {
stack.addFirst(node.right);
}
}
return ans;
}
层序
一般也就迭代写法,用队列配上bfs实现即可`
public List<List<Integer>> levelOrder(TreeNode root) {
Queue<TreeNode> queue = new LinkedList<>();
List<List<Integer>> list = new ArrayList<>();
if (root==null){
return list;
}
queue.offer(root);
while (!queue.isEmpty()){
ArrayList<Integer> temp = new ArrayList<>();
ArrayList<TreeNode> nodetemp = new ArrayList<>();
while (!queue.isEmpty()){
TreeNode node =queue.poll();
nodetemp.add(node);
temp.add(node.val);
}
list.add(temp);
for (TreeNode x:nodetemp){
if (x.left!=null){
queue.offer(x.left);
}
if (x.right!=null){
queue.offer(x.right);
}
}
}
return list;
}