Professional Documents
Culture Documents
HOWKTEAM - VN - BFS Và DFS
HOWKTEAM - VN - BFS Và DFS
Mọi vấn đề về lỗi website làm ảnh hưởng đến bạn hoặc thắc mắc, mong muốn khóa học mới, nhằm hỗ trợ cải thiện Website. Các bạn vui lòng phản hồi
đến Fanpage How Kteam nhé!
Dẫn nhập
Một trong những kĩ thuật cơ bản nhất liên quan đến cây đó chính là duyệt toàn bộ cây đó. Vậy thì có những phương pháp nào để duyệt một cây?
Hãy cùng nhau tìm hiểu trong bài học ngày hôm nay nhé!
Nội dung
Để có thể tiếp thu bài học này một cách tốt nhất, các bạn nên có những kiến thức cơ bản về:
Trong bài học ngày hôm nay, chúng ta sẽ cùng nhau tìm hiểu về:
BFS
DFS
Mở rộng về cây
BFS
Khái niệm
Thuật toán tìm kiếm theo chiều rộng (thường gọi là BFS) là một thuật toán duyệt bắt đầu từ gốc, sau đó lần lượt xét qua các node của một cây theo
ưu tiên về độ sâu từ nhỏ đến lớn.
Ở đây có một khái niệm mới là “độ sâu”. Độ sâu của một node được định nghĩa là số cạnh trên đường đi từ node đang xét đến node gốc.
Ví dụ:
Copyright © Howkteam.com
BFS và DFS 2|6
Đề bài
Cho một cây gồm đỉnh . Hãy in ra các đỉnh được xét lần lượt trong quá trình BFS. Coi đỉnh 1 là gốc.
Input:
dòng tiếp theo: Gồm hai số nguyên thể hiện một cạnh giữa và trên cây
Output:
Dòng 1: Một dòng thể hiện các đỉnh được đi qua theo thứ tự trong quá trình BFS
Ví dụ:
Input Output
8 12635748
12
23
34
25
16
67
38
Cây trong đề bài chính là cây được mình dùng làm ví dụ ở phần khái niệm.
Copyright © Howkteam.com
BFS và DFS 3|6
Trước hết, chúng ta sẽ cần tìm cách để thể hiện một cạnh của cây. Cách được dùng phổ biến nhất là dùng danh sách kề, tức là mỗi node sẽ có một
danh sách lưu lại tất cả các node kề (node có cạnh trực tiếp) với node đó. Trong C++, các bạn có thể dùng vector để lưu danh sách kề. Để biết cụ
thể cách làm, hãy đọc phần code nhé.
Tiếp theo sẽ là cách cái đặt thuật toán BFS . Tư tưởng của BFS đơn giản là như sau:
Code
C++:
#include<bits/stdc++.h>
using namespace std;
int n;
bool mark[MaxN];
vector<int> adj[MaxN];
void BFS(){
queue<int> q;
q.push(1);
while(!q.empty()){
int u = q.front();
q.pop();
mark[u] = 1;
cout << u << " ";
for(int v : adj[u])
if(!mark[v]) q.push(v);
}
}
int main(){
freopen("CTDL.inp","r",stdin);
freopen("CTDL.out","w",stdout);
cin >> n;
for(int i = 0 ; i < n - 1 ; ++i){
int u, v;
cin >> u >> v;
// adj[u] là tập tất cả các đỉnh kề u
// Khi ta thêm đỉnh v vào adj[u] có nghĩa là có cạnh trực tiếp theo hướng từ u tới v
adj[u].push_back(v);
adj[v].push_back(u);
}
BFS();
return 0;
}
Mở rộng
Vừa rồi mình trình bày BFS trên cây. Tuy nhiên, ta có thể tiến hành BFS trên một đơn đồ thị tổng quát với cùng một ý tưởng như trên.
Copyright © Howkteam.com
BFS và DFS 4|6
Độ phức tạp của BFS là trong đó, là số cạnh, là số đỉnh của một đồ thị.
DFS
Khái niệm
Thuật toán tìm kiếm theo chiều sâu (thường gọi là DFS) là một thuật toán duyệt khởi đầu tại node gốc và đi xa nhất có thể theo một nhánh. Các bạn
sẽ rõ hơn về điều này khi ta đi vào phần sau.
Đề bài
Cho một cây gồm đỉnh . Hãy in ra các đỉnh được xét lần lượt trong quá trình DFS. Coi đỉnh 1 là gốc.
Input:
dòng tiếp theo: Gồm hai số nguyên thể hiện một cạnh giữa và trên cây
Output:
Dòng 1: Một dòng thể hiện các đỉnh được đi qua theo thứ tự trong quá trình DFS
Ví dụ:
Input Output
8 12348567
12
23
34
25
16
67
38
Copyright © Howkteam.com
BFS và DFS 5|6
Code
Python:
#include<bits/stdc++.h>
using namespace std;
int n;
bool mark[MaxN];
vector<int> adj[MaxN];
int main(){
freopen("CTDL.inp","r",stdin);
freopen("CTDL.out","w",stdout);
cin >> n;
for(int i = 0 ; i < n - 1 ; ++i){
int u, v;
cin >> u >> v;
// adj[u] là tập tất cả các đỉnh kề u
adj[u].push_back(v);
adj[v].push_back(u);
}
DFS(1);
return 0;
}
Độ phức tạp của DFS giống như BFS và là trong đó, là số cạnh, là số đỉnh của một đồ thị.
Mở rộng
Quan hệ cha - con
Từ quá trình DFS, ta sẽ có một kiểu quan hệ mới giữa hai node trên cây đó là quan hệ “cha – con”. Một node được gọi là node cha của node khi
giữa và có cạnh nối trực tiếp và được xét trước trong quá trình DFS.
Lưu ý: Quan hệ cha – con là quan hệ tương đối, tức là có thể thay đổi phụ thuộc vào cách node gốc được chọn.
Node lá
Một node được gọi là node lá khi nó không có bất cứ một con nào.
Một cây được gọi là cây nhị phân khi mỗi node cha có nhiều nhất hai node con và một node chỉ có duy nhất một node cha.
Ví dụ:
Copyright © Howkteam.com
BFS và DFS 6|6
Kết luận
Qua bài này chúng ta đã nắm được về BFS và DFS
Bài sau chúng ta sẽ tìm hiểu về Segment Tree
Cảm ơn các bạn đã theo dõi bài viết. Hãy để lại bình luận hoặc góp ý của mình để phát triển bài viết tốt hơn. Đừng quên “Luyện tập – Thử
thách – Không ngại khó”.
Copyright © Howkteam.com