Do các thủ tục D_SAU(v) hoặc D_RONG(v) cho phép duyệt tất cả các đỉnh thuộc cùng mảng liên thông với đỉnh v nên số mảng liên thông p của đồ thị G chính bằng số lần gọi đến các [r]
(1)BÀI 12
6.1.3 Duyệt theo chiều rộng (Breadth-First Search)
Nếu thuật toán duyệt đồ thị, cấu trúc danh sách DS tổ chức theo kiểu hàng đợi (danh sách vào trước - trước – FIFO ) ta có phương pháp duyệt theo chiều rộng Trong phương pháp việc duyệt có tính chất “lan rộng” Một đỉnh duyệt xong sau ta xét hết tất đỉnh kề với Đỉnh xét sớm sớm trở thành duyệt xong
Thuật tốn 6.3 (Duyệt đồ thị theo chiều rộng):
Dữ liệu: Biểu diễn mảng DK danh sách kề đồ thị vô hướng G Kết quả: Danh sách đỉnh đồ thị G
1 procedure D_RONG (v) ; begin
3 Q := ∅ ;
4 enqueue v into Q ; { Nạp v vào cuối hàng đợi Q } Duyet [v] := true ;
6 while Q ≠ ∅ begin
8 dequeue z from Q ; { Loại z khỏi đầu hàng đợi Q } 9 Thăm_đỉnh (z) ;
10 for u ∈ DK[z] 11 if ! Duyet [u] then 12 begin
13 enqueue u into Q ;
14 Duyet [u] := true ; 15 end ;
16 end ; 17 end ;
18 BEGIN { Chương trình } 19 for v ∈ V Duyet [v] := false ;
20 for v ∈ V
21 if ! Duyet [v] then D_RONG (v) ; 22 END
Thuật tốn có độ phức tạp là: O(n+m)
(2)Ví dụ 6.2: Đồ thị Ví dụ 6.1 duyệt theo chiều rộng
Hình 6.2 Thứ tự đỉnh duyệt theo chiều rộng
6.2 Một số ứng dụng thuật toán duyệt đồ thị 6.2.1 Bài tốn tìm đường
Giả sử a b hai đỉnh đồ thị vơ hướng G Hãy tìm đường (nếu có) từ đỉnh a đến đỉnh b
Bài toán giải Thuật toán 1.4 thuật toán Warshall Theo phương pháp duyệt đồ thị, lời gọi thủ tục D_SAU(a) D_RONG(a) cho phép thăm tất đỉnh thuộc thành phần liên thơng với đỉnh a Vì vậy, sau thực xong thủ tục Duyet[b] = false khơng có đường từ đỉnh a đên đỉnh b ngược lại đỉnh b thuộc mảng liên thơng với đỉnh a, hay nói cách khác, có đường từ a đến b
Để khôi phục đường ta dùng thêm biến mảng Truoc Thành phần Truoc [u] ghi lại đỉnh đến trước đỉnh u đường duyệt từ a tới u Khi đó, thủ tục D_SAU (v) cần sửa đổi câu lệnh if dòng lệnh sau:
6 if ! Duyet [u] then begin Truoc [u] := v ; D_SAU(u) end ;
còn thủ tục D_RONG (v) cần sửa câu lệnh if dòng lệnh 11-15 là: 11 if ! Duyet [u] then
12 begin
13 enqueue u into Q ;
14 Duyet [u] := true ; Truoc [u] := z
15 end ;
Đường cần tìm (nếu có) khơi phục sau:
(3)Chú ý: Đường tìm theo thuật tốn duyệt theo chiều rộng đường ngắn nhất từ đỉnh a đến đỉnh b
6.2.2 Bài tốn tìm mảng liên thơng
Cho đồ thị G, tìm số mảng liên thơng p đồ thị xác định xem mảng liên thông bao gồm đỉnh
Do thủ tục D_SAU(v) D_RONG(v) cho phép duyệt tất đỉnh thuộc mảng liên thông với đỉnh v nên số mảng liên thông p đồ thị G số lần gọi đến thủ tục chương trình
Để ghi nhận đỉnh mảng liên thông, ta dùng thêm biến mảng Mang[v] để ghi số mảng liên thông chứa đỉnh v Chỉ số tăng từ đến p
Ta dùng biến p để đếm số mảng liên thông đồ thị gán số cho mảng liên thơng tìm Bắt đầu khởi tạo giá trị Thủ tục Thăm_đỉnh(v) thủ tục D_SAU(v) D_RONG(v) làm thêm nhiệm vụ gán:
Mang [v] := p ;
Cịn chương trình thuật toán duyệt cần sửa lại sau: BEGIN { Chương trình } for v ∈ V Duyet [v] := false ;
3 p := ;
4 for v ∈ V
5 if ! Duyet [v] then begin p := p + ;
7 D_SAU (v) ; { D_RONG (v) ; }
8 end ;
9 END