-
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.
add BFS and HEAP code reorganize files and folders
- Loading branch information
1 parent
dccc109
commit 710966c
Showing
6 changed files
with
255 additions
and
0 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
/*BFS_Breadth-First-Search*/ | ||
#include <iostream> | ||
#include <vector> | ||
#include <queue> | ||
using namespace std; | ||
|
||
vector<vector<int>> adj; | ||
|
||
|
||
void printQueue(queue<int> pq) { | ||
//vector<int> temp; | ||
int size = pq.size(); | ||
cout << "q = {"; | ||
for (size_t i = 0; i < size; ++i) { | ||
cout << pq.front() << ", "; | ||
pq.pop(); | ||
} | ||
cout << "}" << endl; | ||
} | ||
void printOrder(vector<int> po) { | ||
cout << "order = {"; | ||
for (size_t i = 0; i < po.size(); ++i) { | ||
cout << po.at(i) << ", "; | ||
} | ||
cout << "}" << endl; | ||
} | ||
void printDiscovered(vector<bool> dp) { | ||
cout << "discovered = {"; | ||
for (size_t i = 0; i < dp.size(); ++i) { | ||
if (dp.at(i)) cout << "T, "; | ||
else cout << "-, "; | ||
} | ||
cout << "}" << endl; | ||
} | ||
|
||
vector<int> bfs(int start) { | ||
queue<int> q; | ||
vector<bool> discovered(adj.size(), false); | ||
vector<int> order; | ||
discovered[start] = true; | ||
printDiscovered(discovered); | ||
q.push(start); | ||
printQueue(q); | ||
cout << endl; | ||
while (!q.empty()) { | ||
int here = q.front(); | ||
cout << "here = q.front :" << here << endl; | ||
q.pop(); | ||
printQueue(q); | ||
order.push_back(here); | ||
printOrder(order); | ||
cout << endl; | ||
for (size_t i = 0; i < adj[here].size(); ++i) { | ||
int there = adj[here][i]; | ||
if (!discovered[there]) { | ||
cout << "there = " << there << endl; | ||
q.push(there); | ||
printQueue(q); | ||
discovered[there] = true; | ||
printDiscovered(discovered); | ||
cout << endl; | ||
} | ||
} | ||
} | ||
return order; | ||
} | ||
|
||
int main() { | ||
adj.resize(8); | ||
int edge; | ||
cout << "간선의 개수를 입력하세요 : "; | ||
cin >> edge; | ||
cout << "각 간선의 두 정점을 입력하세요(ex.a b) " << endl; | ||
for (int i = 0; i < edge; i++) { | ||
int a, b; | ||
cin >> a >> b; | ||
adj[a].push_back(b); | ||
adj[b].push_back(a); | ||
} | ||
vector<int> vv = bfs(0); | ||
printOrder(vv); | ||
|
||
} |
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,86 @@ | ||
## INPUT | ||
|
||
``` | ||
간선의 개수를 입력하세요 : 9 | ||
각 간선의 두 정점을 입력하세요(ex.a b) | ||
0 1 | ||
0 2 | ||
0 3 | ||
1 2 | ||
1 4 | ||
1 5 | ||
2 6 | ||
5 6 | ||
6 7 | ||
``` | ||
|
||
## OUTPUT | ||
|
||
``` | ||
discovered = {T, -, -, -, -, -, -, -, } | ||
q = {0, } | ||
here = q.front :0 | ||
q = {} | ||
order = {0, } | ||
there = 1 | ||
q = {1, } | ||
discovered = {T, T, -, -, -, -, -, -, } | ||
there = 2 | ||
q = {1, 2, } | ||
discovered = {T, T, T, -, -, -, -, -, } | ||
there = 3 | ||
q = {1, 2, 3, } | ||
discovered = {T, T, T, T, -, -, -, -, } | ||
here = q.front :1 | ||
q = {2, 3, } | ||
order = {0, 1, } | ||
there = 4 | ||
q = {2, 3, 4, } | ||
discovered = {T, T, T, T, T, -, -, -, } | ||
there = 5 | ||
q = {2, 3, 4, 5, } | ||
discovered = {T, T, T, T, T, T, -, -, } | ||
here = q.front :2 | ||
q = {3, 4, 5, } | ||
order = {0, 1, 2, } | ||
there = 6 | ||
q = {3, 4, 5, 6, } | ||
discovered = {T, T, T, T, T, T, T, -, } | ||
here = q.front :3 | ||
q = {4, 5, 6, } | ||
order = {0, 1, 2, 3, } | ||
here = q.front :4 | ||
q = {5, 6, } | ||
order = {0, 1, 2, 3, 4, } | ||
here = q.front :5 | ||
q = {6, } | ||
order = {0, 1, 2, 3, 4, 5, } | ||
here = q.front :6 | ||
q = {} | ||
order = {0, 1, 2, 3, 4, 5, 6, } | ||
there = 7 | ||
q = {7, } | ||
discovered = {T, T, T, T, T, T, T, T, } | ||
here = q.front :7 | ||
q = {} | ||
order = {0, 1, 2, 3, 4, 5, 6, 7, } | ||
order = {0, 1, 2, 3, 4, 5, 6, 7, } | ||
``` | ||
|
||
마지막 줄(order = {0, 1, 2, 3, 4, 5, 6, 7, })을 제외한 모든 결과는 알고리즘의 진행과정을 확인하기 위한 것이므로 해당 코드를 생략해도 무방하다. |
File renamed without changes.
File renamed without changes.
File renamed without changes.
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,86 @@ | ||
#include <iostream> | ||
#include <vector> | ||
#include <algorithm> | ||
using namespace std; | ||
#include <iostream> | ||
#include <vector> | ||
#include <algorithm> | ||
using namespace std; | ||
|
||
//힙에 새 원소를 삽입하는 함수 | ||
void push_heap(vector<int>& heap, int newValue) { | ||
heap.push_back(newValue); //새로운 원소를 맨 뒤에 일단 넣어서 모양규칙을 만족시킨다 | ||
int idx = heap.size() - 1; //현재 새로운 원소의 위치는 힙의 제일 마지막 | ||
//모양규칙을 만족했으니 이제 대소관계규칙을 만족시켜볼까~ | ||
//새 원소의 위치가 루트가 아니고 부모의 원소 값이 현재 노드의 값보다 작을 때 반복 | ||
while (idx > 0 && heap[(idx - 1) / 2] < heap[idx]) { | ||
//여기 들어왔다는 건 원소가 루트가 아니고(루트인 경우엔 newValue값이 제일 컸다는 의미. 이제 비교할 원소 없음) | ||
//부모원소 값보다 자식원소 값이 크다는 건데 이 경우에는 힙의 대소관계규칙을 이용해 둘을 바꿔준다. | ||
swap(heap[(idx - 1) / 2], heap[idx]);//부모의 원소와 현재 원소를 바꾼다.(원소 스왑) | ||
idx = (idx - 1) / 2;//그리고는 현재 원소의 위치를 부모위치로 바꿔준다.(주소이전) | ||
} | ||
} | ||
|
||
//우선순위 힙에서 가장 우선순위 높은 원소(=루트) 빼고 나머지 원소 정렬하는 함수 | ||
void pop_heap(vector<int>& heap) { | ||
//루트 원소 빼는 건 여기서 안하고 여기서는 나머지 원소로 다시 힙 정리하는 거 | ||
heap[0] = heap.back(); //일단 힙의 마지막 원소(이하 문제원소)를 비어있는 루트자리에 넣는다. | ||
heap.pop_back(); //힙의 마지막 원소(루트랑 값이 같음)를 팝해준다. | ||
int here = 0; //이건 뭐? //현재 문제 원소의 위치를 변수 here에 저장 | ||
while (1) { //무한반복. 예외는 반복문 안에서 조건문으로 처리함 | ||
int left = here * 2 + 1; //문제원소의 왼쪽 자식의 인덱스 | ||
int right = here * 2 + 2; //문제원소의 오른쪽 자식의 인덱스 | ||
//만약 왼쪽 자식의 인덱스가 힙 크기와 같거나 크면 반복문 종료 | ||
//왜? 모르겠음 일단 패스 | ||
if (left >= heap.size()) break; | ||
int next = here; //문제원소의 인덱스를 일단 변수 next에 저장하고 | ||
//만약 문제원소의 값이 왼쪽 자식의 값보다 작으면 부모값이 자식값보다 커야하는 힙의 대소관계에 어긋나므로 | ||
//왼쪽 자식의 인덱스를 next에 저장한다. | ||
if (heap[next] < heap[left]) next = left; | ||
//만약 오른쪽 자식의 인덱스가 힙의 크기보다 작고 | ||
//문제원소의 값이 오른쪽 자식의 값보다 작은 경우 힙의 대소관계규칙에 어긋나므로 | ||
//오른쪽 자식의 인덱스를 next에 저장한다. | ||
if (right < heap.size() && heap[next] < heap[right]) next = right; | ||
if (next == here) break; //만약 그렇게 저장된 next가 원래 문제원소의 위치였던 here 즉, 루트위치라면 종료 | ||
swap(heap[here], heap[next]); //루트아니라면 임시변수 next와 here의 원소를 서로 바꾼다. | ||
here = next; //그리고 임시변수는 here에 저-장 | ||
} | ||
} | ||
void push_heap(vector<int>& heap, int newValue) { | ||
heap.push_back(newValue); //새로운 원소를 맨 뒤에 일단 넣어서 모양규칙을 만족시킨다 | ||
int idx = heap.size() - 1; //현재 새로운 원소의 위치는 힙의 제일 마지막 | ||
//모양규칙을 만족했으니 이제 대소관계규칙을 만족시켜볼까~ | ||
//새 원소의 위치가 루트가 아니고 부모의 원소 값이 현재 노드의 값보다 작을 때 반복 | ||
while (idx > 0 && heap[(idx - 1) / 2] < heap[idx]) { | ||
//여기 들어왔다는 건 원소가 루트가 아니고(루트인 경우엔 newValue값이 제일 컸다는 의미. 이제 비교할 원소 없음) | ||
//부모원소 값보다 자식원소 값이 크다는 건데 이 경우에는 힙의 대소관계규칙을 이용해 둘을 바꿔준다. | ||
swap(heap[(idx - 1) / 2], heap[idx]);//부모의 원소와 현재 원소를 바꾼다.(원소 스왑) | ||
idx = (idx - 1) / 2;//그리고는 현재 원소의 위치를 부모위치로 바꿔준다.(주소이전) | ||
} | ||
} | ||
|
||
//우선순위 힙에서 가장 우선순위 높은 원소(=루트) 빼고 나머지 원소 정렬하는 함수 | ||
void pop_heap(vector<int>& heap) { | ||
//루트 원소 빼는 건 여기서 안하고 여기서는 나머지 원소로 다시 힙 정리하는 거 | ||
heap[0] = heap.back(); //일단 힙의 마지막 원소(이하 문제원소)를 비어있는 루트자리에 넣는다. | ||
heap.pop_back(); //힙의 마지막 원소(루트랑 값이 같음)를 팝해준다. | ||
int here = 0; //이건 뭐? //현재 문제 원소의 위치를 변수 here에 저장 | ||
while (1) { //무한반복. 예외는 반복문 안에서 조건문으로 처리함 | ||
int left = here * 2 + 1; //문제원소의 왼쪽 자식의 인덱스 | ||
int right = here * 2 + 2; //문제원소의 오른쪽 자식의 인덱스 | ||
//만약 왼쪽 자식의 인덱스가 힙 크기와 같거나 크면 반복문 종료 | ||
//왜? 모르겠음 일단 패스 | ||
if (left >= heap.size()) break; | ||
int next = here; //문제원소의 인덱스를 일단 변수 next에 저장하고 | ||
//만약 문제원소의 값이 왼쪽 자식의 값보다 작으면 부모값이 자식값보다 커야하는 힙의 대소관계에 어긋나므로 | ||
//왼쪽 자식의 인덱스를 next에 저장한다. | ||
if (heap[next] < heap[left]) next = left; | ||
//만약 오른쪽 자식의 인덱스가 힙의 크기보다 작고 | ||
//문제원소의 값이 오른쪽 자식의 값보다 작은 경우 힙의 대소관계규칙에 어긋나므로 | ||
//오른쪽 자식의 인덱스를 next에 저장한다. | ||
if (right < heap.size() && heap[next] < heap[right]) next = right; | ||
if (next == here) break; //만약 그렇게 저장된 next가 원래 문제원소의 위치였던 here 즉, 루트위치라면 종료 | ||
swap(heap[here], heap[next]); //루트아니라면 임시변수 next와 here의 원소를 서로 바꾼다. | ||
here = next; //그리고 임시변수는 here에 저-장 | ||
} | ||
} |