Hàm DFS(Adj,u) có thể viết theo một cách khác, việc kiểm tra đỉnh u đã đánh dấu chưa được đưa vào bên trong hàm như sau:

a) Trong trường hợp này, phần chương trình chính cần viết lại như thế nào?
b) Viết lại toàn bộ chương trình duyệt đồ thị theo chiều sâu theo hàm mô tả trên. Cách duyệt này có tương đương với cách đã thực hiện trong Hoạt động 2 không?
Hàm DFS(Adj,u) có thể viết theo một cách khác, việc kiểm tra đỉnh u đã đánh dấu chưa được đưa vào bên trong hàm như sau:

a) Trong trường hợp này, phần chương trình chính cần viết lại như thế nào?
b) Viết lại toàn bộ chương trình duyệt đồ thị theo chiều sâu theo hàm mô tả trên. Cách duyệt này có tương đương với cách đã thực hiện trong Hoạt động 2 không?
Quảng cáo
Trả lời:
a) Phần chương trình chính cần viết lại:
Phần chính của chương trình sẽ khởi tạo danh sách đánh dấu (mark) và gọi hàm DFS từ đỉnh bắt đầu.
def main(graph, start):
# Khởi tạo mảng đánh dấu cho tất cả các đỉnh
mark = {node: False for node in graph}
# Gọi hàm DFS từ đỉnh bắt đầu
DFS(graph, start, mark)
b) Viết lại toàn bộ chương trình duyệt đồ thị theo chiều sâu:
Dưới đây là toàn bộ chương trình với hàm DFS kiểm tra và đánh dấu đỉnh bên trong hàm:
def DFS(graph, u, mark):
if not mark[u]:
mark[u] = True # Đánh dấu đỉnh u
print("Visit:", u) # In ra đỉnh đang được thăm
for v in graph[u]:
DFS(graph, v, mark)
def main(graph, start):
# Khởi tạo mảng đánh dấu cho tất cả các đỉnh
mark = {node: False for node in graph}
# Gọi hàm DFS từ đỉnh bắt đầu
DFS(graph, start, mark)
# Đồ thị mẫu dưới dạng danh sách kề
graph = {
'A': ['B', 'C'],
'B': ['A', 'D', 'E'],
'C': ['A', 'F'],
'D': ['B'],
'E': ['B', 'F'],
'F': ['C', 'E']
}
# Thực hiện DFS từ đỉnh 'A'
main(graph, 'A')
Giải thích:
1. Hàm DFS:
Kiểm tra nếu đỉnh u chưa được đánh dấu.
Đánh dấu đỉnh u và in ra đỉnh đang được thăm.
Duyệt qua các đỉnh kề của u và gọi đệ quy hàm DFS cho từng đỉnh kề đó.
2. Hàm main:
Khởi tạo danh sách đánh dấu (mark) cho tất cả các đỉnh trong đồ thị.
Gọi hàm DFS từ đỉnh bắt đầu (start).
So sánh với cách đã thực hiện trong Hoạt động 2:
Cách duyệt này về cơ bản là tương đương với cách đã thực hiện trong Hoạt động 2 (không đệ quy) về mặt chức năng, tức là cả hai đều thực hiện duyệt đồ thị theo chiều sâu và đảm bảo tất cả các đỉnh đều được thăm một lần. Tuy nhiên, cách đệ quy này dễ hiểu và ngắn gọn hơn, nhưng có thể gặp vấn đề về ngăn xếp đệ quy nếu đồ thị quá lớn (vượt quá giới hạn ngăn xếp của Python). Trong khi đó, cách không đệ quy thường sử dụng ngăn xếp tự quản lý và phù hợp với các đồ thị lớn hơn trong thực tế.
Hot: 1000+ Đề thi cuối kì 1 file word cấu trúc mới 2025 Toán, Văn, Anh... lớp 1-12 (chỉ từ 60k). Tải ngay
- Sổ tay dẫn chứng nghị luận xã hội năm 2025 (chương trình mới) ( 18.000₫ )
- Sổ tay Ngữ Văn 12 (chương trình mới) ( 18.000₫ )
- Sổ tay lớp 12 các môn Toán, Lí, Hóa, Văn, Sử, Địa, KTPL (chương trình mới) ( 36.000₫ )
- Bộ đề thi tốt nghiệp 2025 các môn Toán, Lí, Hóa, Văn, Anh, Sinh, Sử, Địa, KTPL (có đáp án chi tiết) ( 36.000₫ )
CÂU HỎI HOT CÙNG CHỦ ĐỀ
Lời giải
Ý tưởng chính của DFS:
DFS hoạt động bằng cách bắt đầu từ một đỉnh nguồn, đánh dấu nó là đã thăm, sau đó tiếp tục đi sâu vào các đỉnh kề chưa thăm cho đến khi không thể đi tiếp được nữa. Khi không thể đi tiếp, thuật toán quay lui về các đỉnh trước đó để tiếp tục tìm kiếm các đường đi mới.
Lời giải
Để sửa đổi chương trình của thuật toán DFS không đệ quy sao cho nó in ra thông tin ngăn xếp hiện thời, phần tử được lấy ra từ ngăn xếp, và phần tử được đánh dấu để chuẩn bị cho bước sau, bạn có thể thực hiện như sau:
def dfs(graph, start):
stack = [start] # Ngăn xếp khởi tạo với đỉnh bắt đầu
visited = set() # Tập hợp các đỉnh đã được thăm
while stack:
# In thông tin ngăn xếp hiện thời
print("Stack hiện thời:", stack)
vertex = stack.pop() # Lấy phần tử từ ngăn xếp
print("Phần tử lấy ra từ ngăn xếp:", vertex)
if vertex not in visited:
print("Phần tử được đánh dấu để chuẩn bị cho bước sau (mark):", vertex)
visited.add(vertex) # Đánh dấu phần tử đã thăm
# Thêm các đỉnh kề vào ngăn xếp
for neighbor in reversed(graph[vertex]):
if neighbor not in visited:
stack.append(neighbor)
return visited
# Đồ thị mẫu dưới dạng danh sách kề
graph = {
'A': ['B', 'C'],
'B': ['A', 'D', 'E'],
'C': ['A', 'F'],
'D': ['B'],
'E': ['B', 'F'],
'F': ['C', 'E']
}
# Thực hiện DFS từ đỉnh 'A'
dfs(graph, 'A')
Giải thích:
- Ngăn xếp (Stack): Ban đầu ngăn xếp chứa đỉnh bắt đầu. Mỗi vòng lặp, bạn in ra ngăn xếp hiện thời.
- Phần tử được lấy ra từ ngăn xếp (vertex): Phần tử trên đỉnh ngăn xếp được lấy ra và in ra.
- Phần tử được đánh dấu (mark): Nếu phần tử chưa được thăm, nó được đánh dấu (thêm vào tập visited) và in ra.
Các bước thực hiện:
- Khởi tạo ngăn xếp với đỉnh bắt đầu (start).
- Trong khi ngăn xếp không rỗng:
In thông tin ngăn xếp hiện thời.
Lấy phần tử từ ngăn xếp và in ra.
Nếu phần tử chưa được thăm:
+ Đánh dấu phần tử đã thăm và in ra.
+ Thêm các đỉnh kề vào ngăn xếp theo thứ tự ngược lại để duyệt đúng thứ tự DFS.
Lời giải
Bạn cần đăng ký gói VIP ( giá chỉ từ 199K ) để làm bài, xem đáp án và lời giải chi tiết không giới hạn.
Lời giải
Bạn cần đăng ký gói VIP ( giá chỉ từ 199K ) để làm bài, xem đáp án và lời giải chi tiết không giới hạn.
Lời giải
Bạn cần đăng ký gói VIP ( giá chỉ từ 199K ) để làm bài, xem đáp án và lời giải chi tiết không giới hạn.
Lời giải
Bạn cần đăng ký gói VIP ( giá chỉ từ 199K ) để làm bài, xem đáp án và lời giải chi tiết không giới hạn.
Lời giải
Bạn cần đăng ký gói VIP ( giá chỉ từ 199K ) để làm bài, xem đáp án và lời giải chi tiết không giới hạn.
