-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #3 from deunlee/Study
Add Graph and some refactoring
- Loading branch information
Showing
22 changed files
with
785 additions
and
52 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,124 @@ | ||
#ifndef __DEUN_GRAPH_ADJ_LIST_CPP__ | ||
#define __DEUN_GRAPH_ADJ_LIST_CPP__ | ||
|
||
#include "AdjacencyList.h" | ||
|
||
namespace Deun { | ||
AdjacencyList::AdjacencyList(int vSize) { | ||
if (vSize <= 0) { | ||
this->vSize = 0; | ||
throw AdjacencyListError::MEMORY_ALLOCATION_FAILED; | ||
} | ||
|
||
this->vSize = vSize; | ||
vCount = 0; | ||
list = new (std::nothrow) ALNode*[vSize]; // 포인터 배열 | ||
|
||
if (!list) { | ||
this->vSize = 0; | ||
throw AdjacencyListError::MEMORY_ALLOCATION_FAILED; | ||
} | ||
|
||
for (int i = 0; i < vSize; i++) { | ||
list[i] = nullptr; | ||
} | ||
} | ||
|
||
AdjacencyList::~AdjacencyList() { | ||
clear(); | ||
delete[] list; | ||
} | ||
|
||
int AdjacencyList::insertVertex() { | ||
if (vCount < vSize) { | ||
return vCount++; | ||
} | ||
throw AdjacencyListError::TOO_MANY_VERTICES; | ||
} | ||
|
||
bool AdjacencyList::insertEdge(int from, int to, bool undirected) { | ||
if (from < 0 || from >= vCount || to < 0 || to >= vCount) { | ||
return false; | ||
} | ||
|
||
if (from == to && undirected) { // 두 번 삽입되는 현상 방지 | ||
undirected = false; | ||
} | ||
|
||
ALNode* newNode = new (std::nothrow) ALNode[(undirected ? 2 : 1)]; | ||
if (!newNode) { | ||
return false; | ||
} | ||
|
||
newNode[0].vertex = to; | ||
newNode[0].next = list[from]; | ||
list[from] = &newNode[0]; | ||
|
||
if (undirected) { // 무방향 그래프 (from -> to와 to -> from 모두 삽입) | ||
newNode[1].vertex = from; | ||
newNode[1].next = list[to]; | ||
list[to] = &newNode[1]; | ||
} | ||
|
||
return true; | ||
} | ||
|
||
bool AdjacencyList::hasVertex(int v) { | ||
if (v >= 0 && v < vCount) { | ||
return true; | ||
} | ||
return false; | ||
} | ||
|
||
bool AdjacencyList::hasEdge(int from, int to) { | ||
if (from < 0 || from >= vCount || to < 0 || to >= vCount) { | ||
return false; | ||
} | ||
|
||
ALNode* p = list[from]; | ||
while (p) { | ||
if (p->vertex == to) { | ||
return true; | ||
} | ||
p = p->next; | ||
} | ||
return false; | ||
} | ||
|
||
void AdjacencyList::clear() { | ||
vCount = 0; | ||
for (int i = 0; i < vSize; i++) { | ||
ALNode* p = list[i]; | ||
ALNode* removed; | ||
while (p) { // 연결된 노드 전부 삭제 | ||
removed = p; | ||
p = p->next; | ||
delete removed; | ||
} | ||
list[i] = nullptr; | ||
} | ||
} | ||
|
||
void AdjacencyList::print() { | ||
using namespace std; | ||
|
||
cout << "AdjacencyList(vSize=" << vSize << ", vCount=" << vCount << ")" << endl; | ||
|
||
if (vCount) { | ||
for (int i = 0; i < vCount; i++) { | ||
ALNode* p = list[i]; | ||
cout << i << " -> "; | ||
while (p) { | ||
cout << p->vertex << " -> "; | ||
p = p->next; | ||
} | ||
cout << "null" << endl; | ||
} | ||
} | ||
else { | ||
cout << "(empty)" << endl; | ||
} | ||
} | ||
} | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
#ifndef __DEUN_GRAPH_ADJ_LIST_H__ | ||
#define __DEUN_GRAPH_ADJ_LIST_H__ | ||
|
||
#include <iostream> | ||
#include <new> | ||
|
||
namespace Deun { | ||
enum class AdjacencyListError { | ||
MEMORY_ALLOCATION_FAILED = 1000, | ||
TOO_MANY_VERTICES, | ||
}; | ||
|
||
typedef struct AdjacencyListNode { | ||
int vertex; | ||
struct AdjacencyListNode* next; | ||
} ALNode; | ||
|
||
/** | ||
* 인접 리스트 그래프 (연결 리스트 기반) | ||
*/ | ||
class AdjacencyList { | ||
protected: | ||
int vSize; // 정점의 최대 개수 (메모리 할당량) | ||
int vCount; // 정점의 개수 | ||
ALNode** list; // 연결 리스트 (포인터 배열) | ||
|
||
public: | ||
/** | ||
* 인접 리스트 생성자 | ||
* | ||
* @param {int} vSize: 정점의 최대 개수 | ||
* @throw {AdjacencyListError} 메모리 할당 오류 | ||
*/ | ||
AdjacencyList(int vSize = 1000); | ||
|
||
/** | ||
* 인접 리스트 소멸자 | ||
*/ | ||
~AdjacencyList(); | ||
|
||
/** | ||
* 정점을 삽입하고 삽입된 정점의 인덱스를 반환합니다. | ||
* | ||
* @return {int} 삽입된 정점의 인덱스(0-based) | ||
* @throw {AdjacencyListError} 정점 개수 초과 오류 | ||
*/ | ||
int insertVertex(); | ||
|
||
/** | ||
* 간선을 삽입하고 성공 여부를 반환합니다. | ||
* 간선은 from과 to를 연결하며 방향성이 있습니다. | ||
* undirected가 true인 경우에는 to와 from을 잇는 간선도 삽입합니다. | ||
* | ||
* @param {int} from: 시작 정점 인덱스(0-based) | ||
* @param {int} to: 끝 정점 인덱스(0-based) | ||
* @param {bool} undirected: 무방향 그래프 여부 | ||
* @return {bool} 성공 여부 | ||
*/ | ||
bool insertEdge(int from, int to, bool undirected = false); | ||
|
||
/** | ||
* 정점의 존재 여부를 반환합니다. | ||
* | ||
* @param {int} v: 정점 인덱스(0-based) | ||
* @return {bool} 존재 여부 | ||
*/ | ||
bool hasVertex(int v); | ||
|
||
/** | ||
* 간선의 존재 여부를 반환합니다. | ||
* | ||
* @param {int} from: 시작 정점 인덱스(0-based) | ||
* @param {int} to: 끝 정점 인덱스(0-based) | ||
* @return {bool} 존재 여부 | ||
*/ | ||
bool hasEdge(int from, int to); | ||
|
||
/** | ||
* 인접 행렬을 초기화합니다. | ||
*/ | ||
void clear(); | ||
|
||
/** | ||
* 인접 행렬을 출력합니다. | ||
*/ | ||
void print(); | ||
}; | ||
} | ||
|
||
#endif |
Oops, something went wrong.