200124 자료구조 - 트리 순회 구현
2020-01-24
자료구조 - 트리 순회 구현
트리 순회는 주로 재귀적인 방법으로 구현하지만,
반복적인(iterative) 방법으로 구현할 수도 있다.(스택 등을 이용)
노드가 아래와 같이 정의되어 있는 이진 트리를 순회하는 방식을 다양하게 구현해 보자.
public class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode(int x) { val = x; }
}
재귀적 방법 구현
1) pre-order
class Solution {
ArrayList<Integer> list=new ArrayList<>();
public List<Integer> preorderTraversal(TreeNode root) {
if(root!=null){
list.add(root.val);
preorderTraversal(root.left);
preorderTraversal(root.right);
}
return list;
}
}
2) in-order
class Solution {
ArrayList<Integer> list=new ArrayList<>();
public List<Integer> inorderTraversal(TreeNode root) {
if(root!=null){
inorderTraversal(root.left);
list.add(root.val);
inorderTraversal(root.right);
}
return list;
}
}
3) post-order
class Solution {
ArrayList<Integer> list=new ArrayList<>();
public List<Integer> postorderTraversal(TreeNode root) {
if(root!=null){
postorderTraversal(root.left);
postorderTraversal(root.right);
list.add(root.val);
}
return list;
}
}
반복적 방법 구현
1) pre-order
class Solution {
public List<Integer> preorderTraversal(TreeNode root) {
List<Integer> answer = new ArrayList<>();
Stack<TreeNode> s = new Stack<TreeNode>();
if (root != null) {
s.push(root);
}
TreeNode cur;
while (!s.empty()) {
cur = s.pop();
answer.add(cur.val);
if (cur.right != null) {
s.push(cur.right);
}
if (cur.left != null) {
s.push(cur.left);
}
}
return answer;
}
}
2) in-order
class Solution {
public List<Integer> inorderTraversal(TreeNode root) {
List<Integer> answer = new ArrayList<>();
Stack<TreeNode> s = new Stack<TreeNode>();
TreeNode cur=root;
while (!s.empty() || cur!=null) {
while(cur!=null){
s.push(cur);
cur=cur.left;
}
cur=s.pop();
answer.add(cur.val);
cur=cur.right;
}
return answer;
}
}
왼쪽 노드의 자식이 없을때까지 스택에 값을 누적하면서 내려간다.
왼쪽 자식이 없는 지점에 도착하면 스택의 요소들을 pop하고, 오른쪽 자식 노드를 탐색한다.
3) post-order
class Solution {
public List<Integer> postorderTraversal(TreeNode root) {
List<Integer> answer = new ArrayList<>();
Stack<TreeNode> s = new Stack<TreeNode>();
Stack<TreeNode> t = new Stack<TreeNode>();
TreeNode cur;
if(root!=null)
s.push(root);
while(!s.empty()){
cur=s.pop();
t.push(cur);
if(cur.left!=null)
s.push(cur.left);
if(cur.right!=null)
s.push(cur.right);
}
while(!t.empty()){
cur=t.pop();
answer.add(cur.val);
}
return answer;
}
}
두개의 스택을 사용해 구현한다.
하나의 스택은 역방향 후위순회(루트-오른쪽-왼쪽) 를 구성하기 위해 사용하고,
하나의 스택은 위에서 구성한 순서를 뒤집어 후위순회(왼쪽-오른쪽-루트)를 구성하기 위해 사용한다.
출처