728x90
개요
트리 순회(tree traversal)은 트리의 모든 노드를 한 번씩 방문하는 것이다.
L, V, R이 한 노드에서 각각 왼쪽 이동, 노드 방문, 오른쪽 이동을 나타낸다면 다음과 같다.
- 전위 순회: VLR
- 중위 순회: LVR
- 후위 순회: LRV
트리의 순회는 재귀를 사용하면 쉽게 구현할 수 있다.
트리의 순회 방법은 수식에서의 전위 표기(prefix), 중위 표기(infix), 후위 표기(postfix)가 자연스럽게 대응된다.
이진 트리 구현
#include <iostream>
#include <queue>
template <typename T>
class TreeNode
{
public:
TreeNode(T data)
{
this->data = data;
}
T data;
TreeNode<T>* left = nullptr;
TreeNode<T>* right = nullptr;
};
template <typename T>
class BinaryTree
{
public:
// 빈 이진 트리 생성
BinaryTree() {}
// 왼쪽 서브트리, 오른쪽 서브트리, 값을 갖는
// 이진트리 생성
BinaryTree(BinaryTree<T>* leftSubTree, T data, BinaryTree<T>* rightSubTree)
{
TreeNode<T>* newNode = new TreeNode(data);
if (leftSubTree)
newNode->left = leftSubTree->GetRootNode();
else
newNode->left = nullptr;
if (rightSubTree)
newNode->right = rightSubTree->GetRootNode();
else
newNode->right = nullptr;
root = newNode;
}
~BinaryTree()
{
DeleteAllNode(this->root);
}
void DeleteAllNode(TreeNode<T>* node)
{
if (node)
{
DeleteAllNode(node->left);
DeleteAllNode(node->right);
delete node;
}
}
// 이진 트리 공백 여부
bool IsEmpty()
{
if (this->root)
return false;
else
return true;
}
TreeNode<T>* GetRootNode()
{
if (IsEmpty())
{
std::cout << "Binary tree is empty\n";
return nullptr;
}
else
return this->root;
}
TreeNode<T>* GetLeftSubtree()
{
if (IsEmpty())
{
std::cout << "Binary tree is empty\n";
return nullptr;
}
else
return this->root.left;
}
TreeNode<T>* GetRightSubtree()
{
if (IsEmpty())
{
std::cout << "Binary tree is empty\n";
return nullptr;
}
else
return this->root.right;
}
T RootData()
{
if (IsEmpty())
{
std::cout << "Binary tree is empty\n";
return NULL;
}
else
return this->root.data;
}
private:
TreeNode<T>* root = nullptr; // root node
};
전위 순회 (preorder traversal)
void Preorder(TreeNode<T>* node)
{
if (node) // 널 포인터가 아니면
{
std::cout << node->data << " ";
Preorder(node->left);
Preorder(node->right);
}
}
중위 순회 (inorder traversal)
void Inorder(TreeNode<T>* node)
{
if (node) // 널 포인터가 아니면
{
Inorder(node->left);
std::cout << node->data << " ";
Inorder(node->right);
}
}
후위 순회 (postorder traversal)
void Postorder(TreeNode<T>* node)
{
if (node) // 널 포인터가 아니면
{
Postorder(node->left);
Postorder(node->right);
std::cout << node->data << " ";
}
}
레벨 순서 순회 (level order traversal)
큐를 사용한다.
void LevelOrder()
{
std::queue<TreeNode<T>*> q; // 큐
TreeNode<T>* currNode = root;
while (currNode)
{
std::cout << currNode->data << " ";
if (currNode->left)
q.push(currNode->left);
if (currNode->right)
q.push(currNode->right);
if (q.empty()) return; // 큐 비었으면 리턴
currNode = q.front(); // 다음 노드 => 큐 맨 앞
q.pop();
}
std::cout << "\n";
}
728x90
'Programming > Algorithm & Data Structure' 카테고리의 다른 글
[Algorithm] 힙 정렬 (Heap Sort) (0) | 2025.01.13 |
---|---|
[Data Structure] 힙 트리 (0) | 2025.01.13 |
[Data Structure] 트리, 이진 트리 (0) | 2025.01.12 |
[Data Structure] 이중 연결 리스트 (0) | 2025.01.12 |
[Data Structure] 연결 리스트의 다항식 표현 (0) | 2025.01.12 |