índice
Travessia de árvore binária
A travessia da árvore binária na travessia em profundidade e largura em primeiro
lugar é dividida em preâmbulo, pré-ordem e pós-ordem
Veja: árvore binária conhecida
Podemos entender que a ordem de processamento dos nós é primeiro, meio ou último.
Por exemplo:
Pré-encomenda de travessia
Travessia de pré-ordem da árvore binária
Recursão
public List<Integer> preorderTraversal(TreeNode root) {
List<Integer> list = new ArrayList<>();
if(root == null){
return list;
}
list.add(root.val);
List<Integer> left = preorderTraversal(root.left);
List<Integer> right =preorderTraversal(root.right);
list.addAll(left);
list.addAll(right);
return list;
}
Não recursivo
Idéia:
Preparamos uma pilha com antecedência, salvamos o caminho passado e, em seguida, partimos do nó raiz para a esquerda. Quando o filho da esquerda estiver vazio, encontraremos o filho certo e voltaremos até o final.
class Solution {
public List<Integer> preorderTraversal(TreeNode root) {
List<Integer> list = new ArrayList<>();
if(root == null) {
return list;
}
TreeNode cur = root;
Stack<TreeNode> stack = new Stack<>();
while(cur != null || !stack.isEmpty()){
while(cur != null){
stack.push(cur);
list.add(cur.val);
cur = cur.left;
}
TreeNode pop = stack.pop();
cur = pop.right;
}
return list;
}
}
Travessia em ordem
Travessia em ordem da árvore binária
Recursão
public List<Integer> inorderTraversal(TreeNode root) {
List<Integer> list = new ArrayList<>();
if (root == null) {
return list;
}
List<Integer> left = inorderTraversal(root.left);
list.addAll(left);
list.add(root.val);
List<Integer> right = inorderTraversal(root.right);
list.addAll(right);
return list;
}
Não recursivo
Idéia:
Preparamos uma pilha com antecedência, salvamos o caminho passado e, em seguida, partimos do nó raiz para a esquerda. Quando o filho da esquerda estiver vazio, encontraremos o filho certo e voltaremos até o final.
public List<Integer> inorderTraversal(TreeNode root) {
List<Integer> list = new ArrayList<>();
if (root == null) {
return list;
}
Stack<TreeNode> stack = new Stack<>();
TreeNode cur = root;
while (cur != null || !stack.isEmpty()) {
while (cur != null) {
stack.push(cur);
cur = cur.left;
}
TreeNode node = stack.pop();
list.add(node.val);
cur = node.right;
}
return list;
}
Traversal pós-pedido
Travessia pós-ordem da árvore binária
Recursão
public List<Integer> postorderTraversal1(TreeNode root) {
List<Integer> list = new ArrayList<>();
if (root == null) {
return list;
}
List<Integer> left = postorderTraversal(root.left);
list.addAll(left);
List<Integer> right = postorderTraversal(root.right);
list.addAll(right);
list.add(root.val);
return list;
}
Não recursivo
Ideia:
Em contraste, a travessia pós-ordem não recursiva é um pouco mais problemática do que as duas primeiras, porque não é simplesmente excluir o elemento superior da pilha, se não for bem tratado, causará um loop infinito, então precisamos julgar se a criança certa está vazia, e você acabou de passar pela criança certa.
public List<Integer> postorderTraversal(TreeNode root) {
List<Integer> list = new ArrayList<>();
if (root == null) {
return list;
}
Stack<TreeNode> stack = new Stack<>();
TreeNode cur = root;
TreeNode last = null;
while (cur != null || !stack.isEmpty()) {
while (cur != null) {
stack.push(cur);
cur = cur.left;
}
TreeNode node = stack.peek();
if (node.right == null || node.right == last) {
// 看作第三次经过
list.add(node.val);
last = node;
stack.pop();
} else {
// 第二次经过
cur = node.right;
}
}
return list;
}