π’ κ·Έλνμν
- μν(Traversal) : λͺ¨λ μ μ κ³Ό κ°μ μ κ²μ¬ν¨μΌλ‘μ¨ κ·Έλνλ₯Ό νννλ 체κ³μ μΈ μ μ°¨
- μ£Όμμ λ΅
π κΉμ΄μ°μ νμ(DFS, Depth First Search)
π λλΉμ°μ νμ(BFS, Breadth First Search)
π’ κΉμ΄μ°μ νμ(DFS)
- κΉμ΄μ°μ νμ(DFS, Depth First Search) : κ·Έλνλ₯Ό μννκΈ° μν μΌλ°μ κΈ°λ² μ€ νλ.
- κ·Έλν Gμ λν DFSμνλ‘ κ°λ₯ν κ²λ€
π Gμ λͺ¨λ μ μ κ³Ό κ°μ μ λ°©λ¬Έ
π Gκ° μ°κ²°κ·ΈλνμΈμ§ κ²°μ
π Gμ μ°κ²°μμλ€μ κ³μ°
π Gμ μ μ₯μ²μ κ³μ° - Nκ°μ μ μ κ³Ό Mκ°μ κ°μ μ κ°μ§ κ·Έλνμ λν DFSλ O(N + M)μκ° μμ
- DFSλ₯Ό νμ₯νλ©΄ ν΄κ²° κ°λ₯ν κ·Έλν λ¬Έμ λ€
π λ κ°μ μ£Όμ΄μ§ μ μ μ¬μ΄μ κ²½λ‘λ₯Ό μ°Ύμ 보기
π κ·Έλν λ΄ μΈμ΄ν΄ μ°ΎκΈ° - κ·Έλνμ λν DFSλ μ΄μ§νΈλ¦¬μ λν μ μμνμ μ μ¬νλ€. ( μ μμνλ μ¬κ·, μ¦ μ€ν(Stack)μ νμ©νλ€. )
( μλ£κ΅¬μ‘° μ€νμ λͺ¨λ₯Έλ€λ©΄, μλ ν¬μ€ν μ λ³΄κ³ μ€κΈΈ λ°λλ€. )
Alg DFS(G)
input graph G
output labeling of the edges of G
as tree edges and back edges
for each u ∈ G.vertexs()
l(u) <- Fresh
for each e ∈ G.edges()
l(e) <- Fresh
for each v ∈ G.vertexs()
if(l(v) == Fresh)
rDFS(G,v) // μ¬κ·μ DFS νΈμΆ
=======================================================
Alg rDFS(G,V) // μ¬κ·μ DFS
input graph G and a start vertex v of G
output labeling of the edges of G in the connected
component of v as tree edges and back edges
l(v) <- Visited // λ°©λ¬Έν λ
Έλ 체ν¬
for each e ∈ G.incidentEdges(v) // μ μ vμ λΆμ°©λ κ°μ μ λν΄
if(l(e) == Fresh) // κ°μ eκ° μμ§ μμ§λκ° κ°μ μ΄λ©΄
w <- G.opposite(v,e) // μ μ vμ κ°μ eλ₯Ό ν΅ν λ°λνΈ μ μ w
if(l(w) == Fresh) // wκ° μμ§ λ―Έλ°©λ¬Έ μ μ μ΄λ©΄
l(e) <- Tree // μΌλ¨, κ°μ eλ Fresh -> Tree κ°μ μΌλ‘ λ³κ²½
rDFS(G,w) // rDFS μ¬κ·νΈμΆ
else // κ°μ eκ° Freshν κ°μ μ΄ μλλ€ ?
l(e) <- Back // κ·ΈλΌ, κ°μ eλ Fresh -> Back κ°μ μΌλ‘ λ³κ²½
- DFS μν μμ
- DFS μμ±
π μμ± 1. rDFS(G,v)λ vμ μ°κ²°μμλ΄μ λͺ¨λ μ μ κ³Ό κ°μ μ λ°©λ¬Ένλ€.
π μμ± 2. rDFS(G,V)μ μν΄ λΌλ²¨λ νΈλ¦¬ κ°μ λ€μ vμ μ°κ²°μμμ μ μ₯νΈλ¦¬(DFS tree)λ₯Ό νμ±νλ€. - DFS λΆμ
π μ μ κ³Ό κ°μ μ λΌλ²¨μ μ°κ³ μ½λλ° O(1)μκ° μμ
π κ° μ μ μ λ λ² λΌλ²¨ ( ν λ²μ Fresh, λ νλ²μ Visited )
π κ° κ°μ μ λ λ² λΌλ²¨ ( ν λ²μ Fresh, λ νλ²μ Tree λλ Back μΌλ‘ )
π incidentEdges( ) ( ν μ μ μ λΆμ΄μλ λΆμ°©κ°μ λ©μλ )λ κ° μ μ μ λν΄ ν λ² νΈμΆ
π κ·Έλνκ° μΈμ 리μ€νΈ κ΅¬μ‘°λ‘ ννλ κ²½μ°, DFSλ O(N + M)μκ°μ μν ( μ΄λ€ κ·Έλν Gμ deg(v) ν© = 2M ) - DFS ν
νλ¦Ώ νμ©
π μ°κ²°μ± κ²μ¬, κ²½λ‘ μ°ΎκΈ°, μΈμ΄ν΄ μ°ΎκΈ° λ±μ λ¬Έμ λ€μ DFSλ₯Ό νμ₯ν΄μ ν΄κ²°ν μ μλ€.
π’ λΉμ¬κ·μ DFS
- rDFS ( μ¬κ· DFS )λ μ΄λ¦ κ·Έλλ‘, μ¬κ·νΈμΆμ ν΅ν΄μ κ·Έλν μνλ₯Ό νλ€.
- λΉμ¬κ·μ DFSλ μ¬κ·νΈμΆμ΄ μλ, μ€ν(Stack)μ μ¬μ©ν΄μ DFSλ₯Ό μ€ννλ€.
Alg DFS(G,v)
input graph G and a start vertex v of G
output labeling of the edges of G
in the connected component of v
as tree edges and back edges
S <= empty stack
S.push(v) // 맀κ°λ³μ vμ μ μ€νμ push
while(!(S.isEmpty()) // μ€νμ λΉμΈλμ
v <= S.pop() // μ€ν pop()
l(v) <- Visited // pop()ν μ μ λ,μ΄μ Visited
for each e ∈ G.incidentEdges(v) // pop()ν μ μ μ λΆμ°©λ λͺ¨λ κ°μ μ λν΄
if(l(e) == Fresh) // κ·Έ κ°μ μ΄ μμ§ λ°©λ¬Έμν κ°μ μ΄λ©΄
w <- G.opposite(v,e) // pop()ν μ μ vμ μ°κ²°λ κ°μ eμ λ°λνΈ μ μ μ΄ w
if(l(w) == Fresh) // κ·Έ μ μ wκ° μμ§ λ°©λ¬Έμν μ μ μ΄λ©΄ ?
l(e) <- Tree // 건λμΈ κ°μ eλ μΌλ¨ Fresh -> Tree κ°μ μΌλ‘ λ³κ²½
S.push(w) // κ·Έλ¦¬κ³ , wμ μ μ μ€νμ push
else // μ μ wκ° μ΄λ―Έ λ°©λ¬Έν μ μ μ΄λ©΄
l(e) <- Back // 건λμ¨ κ°μ eλ Fresh -> Back κ°μ μΌλ‘ λ³κ²½ ( μΈμ΄ν΄ μ μ΄ )
return
- μ€μ ꡬν ( By. C )
// DFS λΉμ¬κ·λ²μ Ό
#include <stdio.h>
#include <stdlib.h>
typedef struct incidentedge
{
int key;
char state[6];
struct incidentedge* next;
struct incidentedge* prev;
}IncidentEdge;
typedef struct vertex
{
int key;
char state[6];
IncidentEdge* head;
}Vertex;
typedef struct stack // λΉμ¬κ· DFSλ₯Ό μν stack ( μ μ μ ν€κ°μ μ μ₯ν κ²μ΄λ€. )
{
int* list;
int top;
}Stack;
void nrDFS(Vertex* V, int S, int n); // λΉμ¬κ· DFS
void makeVertex(Vertex* V, int n);
void linkEdge(Vertex* V, int start, int end);
void initStack(Stack* S, int n); // μ€ν μ΄κΈ°ν
void push(Stack* S, int n); // μ€ν push
int pop(Stack* S); // μ€ν pop
int isStackEmpty(Stack* S); // μ€ν λΉμλκ° ?
void freeVertexIncidentList(Vertex* V, int n);
int main()
{
int N, M, S, start, end;
Vertex* v = NULL;
scanf("%d %d %d", &N, &M, &S);
v = (Vertex*)malloc(sizeof(Vertex) * N);
makeVertex(v, N);
for (int i = 0; i < M; i++)
{
scanf("%d %d", &start, &end);
linkEdge(v, start, end);
linkEdge(v, end, start);
}
nrDFS(v,S,N); // λΉμ¬κ· DFS νΈμΆλ§ λ€λ₯Έ λΆλΆ
freeVertexIncidentList(v, N); // κ° μ μ μ λ¬λ¦°, μΈμ 리μ€νΈ λμ ν λΉ ν΄μ
for (int i = 0; i < N; i++)
free(v[i].head); // κ° μ μ μ λ¬λ¦°, μΈμ ν€λ λμ ν λΉ ν΄μ
free(v); // μ μ λ°°μ΄ λμ ν λΉ ν΄μ
return 0;
}
void nrDFS(Vertex* V,int s,int n) // λΉμ¬κ·μ DFS
{
IncidentEdge* p = NULL; // μΈμ 리μ€νΈ μ‘°μ¬ν p
Stack* stack = NULL; // μ€ν ν¬μΈν°
stack = (Stack*)malloc(sizeof(Stack)); // μ€ν λμ ν λΉ
initStack(stack,n); // μ€ν μ΄κΈ°ν
push(stack, V[s - 1].key); // νλΌλ―Έν°λ‘ λμ΄μ¨ s, μ μ sλΆν° μμ, μ€νμ push
strcpy(V[s - 1].state, "visit"); // μ μ s λ μ΄μ visit
printf("%d\n", V[s-1].key); // λ°©λ¬Έμλ―Ένλ μΆλ ₯
while (!isStackEmpty(stack)) // μ΄μ λΆν° μ€νμ΄ λΉμΈ λκΉμ§ λ°λ³΅ν κ²μ
{
// 맀 μ°¨λ‘λ§λ€
p = V[stack->list[stack->top]-1].head->next; // μ€νμ κ°μ₯ μ΅κ·Όμ λ€μ΄μ¨, μ μ μμΉμ, μΈμ λ
Έλ μμμ pμ λμ
ν΄μ
while (p != NULL && strcmp(V[p->key - 1].state, "visit") == 0) // μΈμ ν΄ μλλ°, μμ§ λ°©λ¬Έμν, μ μ μ°Ύμ
p = p->next;
if (p != NULL && strcmp(V[p->key-1].state,"fresh") == 0) // μμ§ λ°©λ¬Έμν, μΈμ ν μ μ μ΄ μμΌλ©΄
{
push(stack, V[p->key - 1].key); // κ·Έ μ μ , μ€νμ push
strcpy(V[p->key - 1].state, "visit"); // κ·Έ μ μ μ μ΄μ , visit
printf("%d\n", V[p->key - 1].key); // κ·Έ μ μ μΌλ‘, λ°©λ¬Ένμμ μλ―Έ,μΆλ ₯
}
if (p == NULL) // μ whileλ¬Έμ ν΅ν΄μ, νμ¬ stackμ peekν μ μ μ, μΈμ μ μ μ λ€ λ°©λ¬ΈνμΌλ©΄
pop(stack); // κ·Έ μ μ μ, μ΄μ λ€μ΄κ° λ§νΌ λ€μ΄κ° κ²μ΄λ, pop
}
free(stack->list); // μ€ν 리μ€νΈ λμ ν λΉ ν΄μ
free(stack); // μ€ν λμ ν λΉ ν΄μ
}
void makeVertex(Vertex* V, int n)
{
for (int i = 0; i < n; i++)
{
V[i].key = i + 1;
strcpy(V[i].state, "fresh");
V[i].head = (IncidentEdge*)malloc(sizeof(IncidentEdge));
if (V[i].head != NULL)
{
V[i].head->next = NULL;
V[i].head->key = 0;
}
}
}
void linkEdge(Vertex* V, int start, int end)
{
IncidentEdge* p, * newNode;
newNode = (IncidentEdge*)malloc(sizeof(IncidentEdge));
if (newNode != NULL)
{
newNode->key = end;
newNode->prev = NULL;
newNode->next = NULL;
strcpy(newNode->state, "fresh");
}
p = V[start - 1].head;
while (p->next != NULL && end > p->next->key)
p = p->next;
if (p->next == NULL)
{
p->next = newNode;
newNode->prev = p;
}
else
{
newNode->next = p->next;
p->next->prev = newNode;
newNode->prev = p;
p->next = newNode;
}
}
void initStack(Stack* S, int n)
{
S->list = (int*)malloc(sizeof(int) * n);
S->top = -1;
}
void push(Stack* S, int n)
{
S->top += 1;
S->list[S->top] = n;
}
int pop(Stack* S)
{
int returnData = S->list[S->top];
S->top -= 1;
return returnData;
}
int isStackEmpty(Stack* S)
{
return S->top == -1;
}
void freeVertexIncidentList(Vertex* V, int n)
{
IncidentEdge* p = NULL;
for (int i = 0; i < n; i++)
{
while (V[i].head->next != NULL)
{
p = V[i].head->next;
while (p->next != NULL) p = p->next;
p->prev->next = NULL;
free(p);
}
}
}
π’ λλΉμ°μ νμ(BFS)
- λλΉμ°μ νμ(BFS, Breadth First Search) : κ·Έλνλ₯Ό μννκΈ° μν μΌλ°μ κΈ°λ² μ€ νλ.
- κ·Έλν Gμ λν BFSμνλ‘ κ°λ₯ν κ²λ€
π Gμ λͺ¨λ μ μ κ³Ό κ°μ μ λ°©λ¬Έ
π Gκ° μ°κ²°κ·ΈλνμΈμ§ κ²°μ
π Gμ μ°κ²°μμλ€μ κ³μ°
π Gμ μ μ₯μ²μ κ³μ° - Nκ°μ μ μ κ³Ό Mκ°μ κ°μ μ κ°μ§ κ·Έλνμ λν BFSλ O(N + M)μκ° μμ
- BFSλ₯Ό νμ₯νλ©΄ ν΄κ²° κ°λ₯ν κ·Έλν λ¬Έμ λ€
π λ κ°μ μ£Όμ΄μ§ μ μ μ¬μ΄μ μ΅μ κ°μ μ μ¬μ©νλ κ²½λ‘λ₯Ό μ°Ύμ보기
π κ·Έλν λ΄ λ¨μμΈμ΄ν΄ μ°ΎκΈ° - κ·Έλνμ λν BFSλ μ΄μ§νΈλ¦¬μ λν λ 벨μνμ μ μ¬νλ€. ( λ 벨μνλ ν(Queue)λ₯Ό νμ©νμλ€. )
( μλ£κ΅¬μ‘°μ λ 벨μνλ₯Ό λͺ¨λ₯Έλ€λ©΄, μλ ν¬μ€ν μ νμΈνκ³ μ€κΈΈ λ°λλ€. )
Alg BFS(G)
input graph G
output labeling of the edges of G
as tree edges and cross edges
for each u ∈ G.vertexs()
l(u) <- Fresh
for each e ∈ G.edges()
l(e) <- Fresh
for each v ∈ G.vertexs()
if(l(v) == Fresh)
BFS1(G,v)
=======================================
Alg BFS1(G,v)
input graph G and a start vertex v of G
output labeling of the edges of G
in the connected component of v as tree
edges and cross edges
L(0) <- empty list // λ 벨μν ν(queue)
L(0).addLast(v) // νμ 맀κ°λ³μλ‘ λμ΄μ¨, μ μ v λ₯Ό enqueue
l(v) <- Visited // μ μ μ νμ enqueue νλ€λ κ²μ, λ°©λ¬Ένλ€λ μλ―Έ. κ³ λ‘ μ μ vλ₯Ό Fresh -> Visited
i <- 0 // ν μΈλ±μ±ν i
while(!(L(i).isEmpty()) // νλ₯Ό λΉμΈλκΉμ§
L(i+1) <- empty list
for each v ∈ L(i).elements() // νμ μλ μ μ νλλ₯Ό dequeueλ₯Ό νκ³
for each e ∈ G.incidentEdges(v) // κ·Έ μ μ κ³Ό μ°κ²°λ λͺ¨λ κ°μ μ λν΄
if(l(e) == Fresh) // μμ§ λ°©λ¬Έμν΄λ³Έ κ°μ μ΄λ©΄ κ°μ
w <- G.opposite(v,e) // κ·Έ μ μ vμ κ°μ eλ₯Ό ν΅ν λ°λνΈ μ μ μ wλΌ νκ³
if(l(w) == Fresh) // κ·Έ μ μ wκ° μμ§ λ°©λ¬Έμν μ μ μ΄λ©΄
l(e) <- Tree // κ°μ eλ Fresh -> Tree κ°μ μΌλ‘
l(w) <- Visited) // μ μ wλ Fresh -> Visited μ μ μΌλ‘ λ³κ²½νκ³
L(i+1).addLast(w) // μ μ wλ₯Ό νμ enqueue
else // μ μ wκ° μ΄λ―Έ λ°©λ¬Έν μ μ μ΄λΌλ©΄
l(e) <- Cross // κ°μ eλ Fresh -> Cross κ°μ μΌλ‘
i <- i + 1
- BFS μν μμ
- BFS μμ±
π G(v) : vμ μ°κ²°μμλΌ νμ λ
π μμ± 1. BFS1(G,v)λ G(v)μ λͺ¨λ μ μ κ³Ό κ°μ μ λ°©λ¬Ένλ€.
π μμ± 2. BFS1(G,v)μ μν΄ λΌλ²¨λ νΈλ¦¬ κ°μ λ€μ G(v)μ μ μ₯νΈλ¦¬(BFS tree)λΌ λΆλ¦°λ€. ( T(v) )
π μμ± 3. L(i)λ΄μ κ° μ μ wμ λν΄
1. T(v)μ vμμ wλ‘ ν₯νλ κ²½λ‘λ iκ°μ κ°μ μ κ°μ§λ€.
2. G(v)λ΄μ vμμ wλ‘ ν₯νλ λͺ¨λ κ²½λ‘λ μ΅μ iκ° κ°μ μ κ°μ§λ€. - BFS λΆμ
π μ μ κ³Ό κ°μ μ λΌλ²¨μ μ°κ³ μ½λλ° O(1) μκ°μμ
π κ° μ μ μ λ λ² λΌλ²¨ ( ν λ²μ Freshλ‘ , λ ν λ²μ Visited λ‘ )
π κ° κ°μ μ λ λ² λΌλ²¨ ( ν λ²μ Freshλ‘ , λ ν λ²μ Tree λλ Cross λ‘ )
π κ° μ μ μ 리μ€νΈ L(i)μ ν λ² μ½μ ( μ¬κΈ°μ 리μ€νΈλ ν(queue)λ₯Ό μλ―Έ )
π incidentEdges( ) ( λΆμ°©κ°μ λ©μλ )λ κ° μ μ μ λν΄ ν λ² νΈμΆ
π κ·Έλν Gκ° μΈμ 리μ€νΈ κ΅¬μ‘°λ‘ ννλ κ²½μ°, BFSλ O(N + M)μκ°μ μν - BFS ν
νλ¦Ώ νμ©
π Gμ μ°κ²°μμλ€μ κ³μ°νκΈ°
π Gμ μ μ₯μ²μ κ³μ°νκΈ°
π Gλ΄μ λ¨μ μΈμ΄ν΄ μ°ΎκΈ° λλ Gκ° μ²μμ λ³΄κ³ νκΈ°
π Gμ μ£Όμ΄μ§ λ μ μ μ λν΄, κ·Έ μ¬μ΄μ μ΅μ κ°μ λ‘ μ΄λ£¨μ΄μ§ G λ΄μ κ²½λ‘ μ°ΎκΈ°, λλ κ·Έλ° κ²½λ‘ μμμ μ°ΎκΈ°
( μ¦, μ΅λ¨ κ²½λ‘(Directed Path) λ¬Έμ νμ© κ°λ₯ )
728x90
λ°μν
'Algorithm Theory' μΉ΄ν κ³ λ¦¬μ λ€λ₯Έ κΈ
λμ νλ‘κ·Έλλ°(Dynamic Programming) (0) | 2020.12.14 |
---|---|
λ°©ν₯ κ·Έλν(Directed graph) (0) | 2020.12.14 |
κ·Έλν(Graph) (0) | 2020.12.13 |
ν΄μν μ΄λΈ(Hash Table) (0) | 2020.12.13 |
μ΄μ§νμνΈλ¦¬(Binary Search Tree) (0) | 2020.12.12 |