일지
알고리즘...106
niamdank
2022. 1. 24. 21:27
그래프 구현 준비
그래프는 다음의 표현 방식이 존재한다.
- 인접 행렬 표현 방식
- 인접 리스트 표현 방식
그래프는 다음의 종류가 존재한다.
- 방향 그래프
- 무방향 그래프
그래프의 순회는 다음의 방법을 쓸 수 있다.
- 너비 우선 탐색(BFS)
- 깊이 우선 탐색(DFS)
또, 그래프는 필요에 따라 가중치를 표현할 수 있다.
이에 따라 클래스의 생성자에서 방향, 무방향 그래프를 설정하고 그래프를 출력할 때 순회 방법을 선택할 수 있도록 한다.
Graph.h
#pragma once
#include "../Common.h"
#include <cmath>
#include <string>
#include <vector>
using std::string;
using std::vector;
/// <summary>
/// 그래프의 간선 처리 방식
/// </summary>
enum class GraphOption
{
Undirected,
Directed,
};
/// <summary>
/// 그래프의 순회 방식
/// </summary>
enum class GraphTraversal
{
BFS,
DFS,
};
/// <summary>
/// 그래프 노드를 나타내기 위한 구조체
/// </summary>
struct GraphNode
{
GraphNode(string name) : name(name) {}
string name;
};
/// <summary>
/// 그래프의 구성 요소 테스트를 위한 베이스 클래스
/// </summary>
class Graph
{
public:
Graph(GraphOption graphOption = GraphOption::Undirected) : m_graphOption(graphOption) {};
virtual void AddNode(string name);
virtual void AddEdge(string from, string to, int weight = 1) = 0;
virtual void RemoveNode(string name) = 0;
virtual void RemoveEdge(string from, string to) = 0;
virtual void Clear() = 0;
virtual void PrintGraph(GraphTraversal graphTraversal = GraphTraversal::BFS, string graphName = "Graph");
bool Exists(string name);
int GetNodeIndex(string name);
private:
string GetGraphOptionString();
string GetGraphTraversalString(GraphTraversal graphTraversal);
protected:
GraphOption CurrentHashFunction() { return m_graphOption; }
private:
GraphOption m_graphOption;
vector<GraphNode> m_graphNodeList;
};
Graph.cpp
#include "Graph.h"
#pragma region Public Functions
/// <summary>
/// 그래프에 노드를 추가한다.
/// </summary>
/// <param name="name">추가할 노드 이름</param>
void Graph::AddNode(string name)
{
if (Exists(name))
{
return;
}
for (size_t total = m_graphNodeList.size(), i = 0; i < total; i++)
{
if (m_graphNodeList[i].name == "")
{
m_graphNodeList[i].name = name;
return;
}
}
m_graphNodeList.push_back(GraphNode(name));
}
/// <summary>
/// 해시 테이블의 현 상태를 출력한다.
/// </summary>
void Graph::PrintGraph(GraphTraversal graphTraversal, string graphName)
{
std::cout << "------------------------------------------\n";
std::cout << "- Class Name : " << graphName << '\n';
std::cout << "- GraphOption : " << GetGraphOptionString() << '\n';
std::cout << "- GraphTraversal : " << GetGraphTraversalString(graphTraversal) << '\n';
std::cout << "- Graph Nodes\n";
if (m_graphNodeList.empty())
{
std::cout << "EMPTY\n";
}
else
{
for (size_t total = m_graphNodeList.size(), i = 0; i < total; i++)
{
std::cout << "Index[" << i << "] : ";
if (m_graphNodeList[i].name == "")
{
std::cout << "None";
}
else
{
std::cout << m_graphNodeList[i].name;
}
if (i < total - 1)
{
std::cout << " - ";
}
}
}
std::cout << "------------------------------------------\n";
}
/// <summary>
/// 주어진 이름의 노드가 존재하는지 여부를 반환한다.
/// </summary>
/// <param name="name">검색할 노드의 이름</param>
/// <returns>존재 여부</returns>
bool Graph::Exists(string name)
{
for (size_t total = m_graphNodeList.size(), i = 0; i < total; i++)
{
if (m_graphNodeList[i].name == name)
{
return true;
}
}
return false;
}
/// <summary>
/// 그래프에 주어진 이름을 가진 노드의 인덱스를 검색하여 반환한다.
/// </summary>
/// <param name="name">검색할 노드의 이름</param>
/// <returns>노드의 인덱스(없으면 -1)</returns>
int Graph::GetNodeIndex(string name)
{
for (size_t total = m_graphNodeList.size(), i = 0; i < total; i++)
{
if (m_graphNodeList[i].name == name)
{
return static_cast<int>(i);
}
}
return -1;
}
#pragma endregion
#pragma region Private Functions
/// <summary>
/// 현재 그래프 옵션을 string 으로 반환한다.
/// </summary>
/// <returns>그래프 옵션 string</returns>
std::string Graph::GetGraphOptionString()
{
if (m_graphOption == GraphOption::Undirected)
{
return "Undirected";
}
return "Directed";
}
/// <summary>
/// 주어진 그래프 순회 옵션을 string 으로 변환한다.
/// </summary>
/// <param name="graphTraversal">그래프 순회 방법</param>
/// <returns>그래프 순회 방법 string</returns>
string Graph::GetGraphTraversalString(GraphTraversal graphTraversal)
{
if (graphTraversal == GraphTraversal::BFS)
{
return "BFS";
}
return "DFS";
}
#pragma endregion
NadanKim/Algorithm: 알고리즘 학습 및 예제 코드 작성을 위한 저장소 (github.com)
GitHub - NadanKim/Algorithm: 알고리즘 학습 및 예제 코드 작성을 위한 저장소
알고리즘 학습 및 예제 코드 작성을 위한 저장소. Contribute to NadanKim/Algorithm development by creating an account on GitHub.
github.com