공부/알고리즘 (c++)

트리 기초

원클릭쓰리버그 2022. 2. 7. 20:56
728x90

 

트리란? 

기존의 그래프와 비슷하게 노드와 가지(edge)로 이루어져 있는 트리 알고리즘은 그래프와 다르게 계층이 나뉘어져 있는게 특징이다. 그래프의 노드는 동등한 입장이라면, 트리는 노드간의 계층이 존재하여 부모 혹은 루트로 이루어져 있는걸 볼 수 있다. 

 

이는 조직도 혹은 폴더 등에서 많이 볼 수 있는 구조이다.

 

 

  • Root Node : 트리 구조에서 최상위에 존재하는 A와 같은 노드
  • Node : 트리의 구성요소에 해당하는 A,B,C,D,E,F,G,H,I,J와 같은 요소
  • Edge : 노드와 노드를 연결하는 연결설
  • Terminal Node(Leaf Node) : 밑으로 또 다른 노드가 연결되어 있지 않은 H,I,J,F,G와 같은 노드
  • Sub-Tree : 큰 트리(전체)에 속하는 작은 트리
  • Level : 트리에서 각 층별로 숫자를 매김
  • Height : 트리의 최고 레벨 (3)

 

 

구현하면서 새로운 지식을 알게 되었는데, 자기 자신을 가리키는 포인터를 사용할 때, 동적할당 및 해제를 자동으로 해주는 기능을 처음 알게 되었다.

 

using NodeRef = shared_ptr<struct Node>;

struct Node
{
	string data;
	vector<NodeRef> children;
};

 

여기서 shared_ptr<>는 스마트 포인터라고 불리는데,

 

스마트 포인터(smart pointer)

C++ 프로그램에서 new 키워드를 사용하여 동적으로 할당받은 메모리는, 반드시 delete 키워드를 사용하여 해제해야 합니다.

C++에서는 메모리 누수(memory leak)로부터 프로그램의 안전성을 보장하기 위해 스마트 포인터를 제공하고 있습니다.

스마트 포인터(smart pointer)란 포인터처럼 동작하는 클래스 템플릿으로, 사용이 끝난 메모리를 자동으로 해제해 줍니다.

 

자세한 내용

http://www.tcpschool.com/cpp/cpp_template_smartPointer

 

코딩교육 티씨피스쿨

4차산업혁명, 코딩교육, 소프트웨어교육, 코딩기초, SW코딩, 기초코딩부터 자바 파이썬 등

tcpschool.com

을 참고하자.

 

 

#include <iostream>
#include <vector>
#include <queue>
#include <stack>
#include <list>
using namespace std;

using NodeRef = shared_ptr<struct Node>;

struct Node
{
	Node() {}
	Node(const string& data) : data(data) {}

	string data;
	vector<NodeRef> children;
};


NodeRef CreateTree()
{
	NodeRef root = make_shared<Node>("R1 개발실");
	{
		NodeRef node = make_shared<Node>("디자인팀");
		root->children.push_back(node);
		{
			NodeRef leaf = make_shared<Node>("전투");
			node->children.push_back(leaf);
		}
		{
			NodeRef leaf = make_shared<Node>("경제");
			node->children.push_back(leaf);
		}
		{
			NodeRef leaf = make_shared<Node>("스토리");
			node->children.push_back(leaf);
		}
	}
	{
		NodeRef node = make_shared<Node>("프로그래밍팀");
		root->children.push_back(node);
		{
			NodeRef leaf = make_shared<Node>("서버");
			node->children.push_back(leaf);
		}
		{
			NodeRef leaf = make_shared<Node>("클라이언트");
			node->children.push_back(leaf);
		}
		{
			NodeRef leaf = make_shared<Node>("엔진");
			node->children.push_back(leaf);
		}
	}
	{
		NodeRef node = make_shared<Node>("디자인팀");
		root->children.push_back(node);
		{
			NodeRef leaf = make_shared<Node>("배경");
			node->children.push_back(leaf);
		}
		{
			NodeRef leaf = make_shared<Node>("캐릭터");
			node->children.push_back(leaf);
		}
	}

	return root;
}

void PrintTree(NodeRef root, int depth)
{

	for (size_t i = 0; i < depth; i++)
	{
		cout << "-";
	}
	cout << root->data << endl;

	for (NodeRef& child : root->children)
	{
		PrintTree(child,depth+1);
	}
}

int main()
{
	NodeRef root =  CreateTree();

	PrintTree(root,0);

}

코드는 위와 같이 구현을 할 수 있다. 

최상위 Root = R1 개발실을 만들고,

하위에 Root의 children의 디자인팀, 프로그래밍팀, 기획팀을 만든다.

마지막 하위인 Leaf은 하위 Root의 children으로 들어가게 된다. 결과적으로 

 

이런 결과 값이 나오게 된다.

 

여기서 만약 높이(height) : (루트의 가장 긴 깊이(depth)) 를 구하고 싶다면, 이러한 코드를 통해 높이를 얻을 수 있다.

 

int GetHeight(NodeRef root)
{
	int height = 1;

	for (NodeRef& child : root->children)
	{
		height = max(height,GetHeight(child) + 1);
	}

	return height;
}

 

 

 

 

참고 

https://monsieursongsong.tistory.com/6

 

[알고리즘] 2.3.자료구조 : 트리(Tree) 이해하기와 구현

  개요 앞서 보인 큐(Queue), 스택(Stack) 등은 자료구조에서 선형 구조라 한다. 선형 구조란 자료를 구성하고 있는 데이터들이 순차적으로 나열시킨 형태를 의미합니다. 이번에 배울 트리는 비선

monsieursongsong.tistory.com

 

'공부 > 알고리즘 (c++)' 카테고리의 다른 글

우선순위 큐 (PriorityQueue)  (0) 2022.02.14
힙 이론  (0) 2022.02.09
다익스트라 알고리즘  (0) 2022.01.26
BFS (Breadth First Search) 너비 우선 탐색  (0) 2022.01.22
DFS (Depth First Search) 깊이 우선 탐색  (0) 2022.01.22