|
Serwis Edukacyjny w I-LO w Tarnowie
Materiały dla uczniów liceum |
Wyjście Spis treści Wstecz Dalej
Autor artykułu: mgr Jerzy Wałaszek |
©2026 mgr Jerzy Wałaszek
|
ProblemNależy wykonać przejście grafu wszerz. |
Algorytm przechodzenia wszerz (ang. breadth-first search, BFS) opisaliśmy już przy przechodzeniu drzew binarnych. Dla grafu działa on następująco:
Tutaj również musimy posiłkować się dodatkowym parametrem vs, jak przy algorytmie DFS, aby uniknąć zapętlenia w przypadku napotkania cyklu. Przypominam: parametr vs określa stan odwiedzin wierzchołka. Wartość false posiada wierzchołek jeszcze nie odwiedzony, a wartość true ma wierzchołek, który algorytm już odwiedził. Parametry te są zebrane w tablicy logicznej vs, która posiada tyle elementów, ile jest wierzchołków w grafie. Element vs[i] odnosi się do wierzchołka grafu o numerze i.
Prześledźmy działanie tego algorytmu na przykładowym grafie.
![]() |
Rozpoczynamy od wierzchołka startowego. |
![]() |
Wierzchołek startowy zaznaczamy jako odwiedzony (zielony) i odwiedzamy wszystkich jego sąsiadów pierwszego poziomu. |
![]() |
Sąsiadów pierwszego poziomu oznaczamy jako odwiedzonych i odwiedzamy wszystkich ich sąsiadów, którzy jeszcze nie zostali odwiedzeni. |
![]() |
Sąsiadów drugiego poziomu oznaczamy jako odwiedzonych i odwiedzamy wszystkich ich sąsiadów, którzy jeszcze nie byli odwiedzeni. |
![]() |
Sąsiadów trzeciego poziomu oznaczamy jako odwiedzonych i odwiedzamy wszystkich ich sąsiadów, którzy jeszcze nie byli odwiedzeni. Do odwiedzenia jest teraz tylko jeden taki wierzchołek. |
![]() |
Sąsiada czwartego poziomu oznaczamy jako odwiedzonego i odwiedzamy wszystkich jego sąsiadów, którzy jeszcze nie byli odwiedzeni. Do odwiedzenia jest znów tylko jeden taki wierzchołek. |
![]() |
Sąsiada piątego poziomu oznaczamy jako odwiedzonego i odwiedzamy wszystkich jego sąsiadów, którzy jeszcze nie byli odwiedzeni. Do odwiedzenia pozostały dwa ostatnie wierzchołki. |
![]() |
Oznaczamy jako odwiedzonych dwóch sąsiadów stopnia 6. W grafie nie ma już nieodwiedzonych wierzchołków. Przejście BFS zostało zakończone. |
Taki sposób odwiedzania wierzchołków wymaga kolejki.
Powód jest bardzo prosty. Kolejka jest sekwencyjną strukturą danych, z której
odczytujemy elementy w kolejności ich zapisu. Na koniec kolejki wstawiamy
wierzchołek startowy. Wewnątrz pętli wierzchołek ten zostanie odczytany z początku
kolejki, po czym algorytm umieści w niej wszystkich nieodwiedzonych sąsiadów.
W kolejnych obiegach pętli sąsiedzi ci (sąsiedzi poziomu 1)
zostaną odczytani z początku kolejki, a na jej koniec zostaną wstawieni
sąsiedzi
K01: Q.push(v) ; w kolejce umieszczamy numer wierzchołka startowego K02: vs[v] ← true; ; oznaczamy wierzchołek jako odwiedzony K03: Dopóki Q.empty() = false, ; tutaj jest pętla główna algorytmu BFS wykonuj kroki K04…K10 K04: v ← Q.front() ; odczytujemy z kolejki numer wierzchołka K05: Q.pop() ; odczytany numer wierzchołka usuwamy z kolejki K06: Przetwórz wierzchołek v ; tutaj wykonujemy operacje na wierzchołku v K07: Dla każdego sąsiada u wierzchołka v, ; przeglądamy wszystkich sąsiadów v wykonuj kroki K08…K10 K08: Jeśli vs[u] = true, ; szukamy nieodwiedzonego sąsiada to następny obieg pętli K07 K09: Q.push(u) ; umieszczamy go w kolejce K10: vs[u] ← true ; i oznaczamy jako odwiedzonego K11: Zakończ
Algorytm szczegółowy zależy od wybranego sposobu reprezentacji grafu
w pamięci komputera. Zmiany będą dotyczyły tylko kroku K08, w którym należy
znaleźć wszystkich nieodwiedzonych sąsiadów
K01: Q.push(v) ; w kolejce umieszczamy numer wierzchołka startowego K02: vs[v] ← true K03: Dopóki Q.empty() = false, ; tutaj jest pętla główna algorytmu BFS wykonuj kroki K04…K10 K04: v ← Q.front() ; odczytujemy z kolejki numer wierzchołka K05: Q.pop() ; odczytany numer usuwamy z kolejki K06: Przetwórz wierzchołek v ; tutaj wykonujemy operacje na wierzchołku v K07: Dla i = 0, 1, …, n-1, ; przeglądamy wszystkich sąsiadów v wykonuj kroki K08…K10 K08: Jeśli (A[v][i] = 0)(vs[i] = true), ; szukamy nieodwiedzonego sąsiada to następny obieg pętli K07 K09: Q.push(i) ; numer sąsiada umieszczamy w kolejce K10: vs[i] ← true ; i oznaczamy go jako odwiedzonego K11: Zakończ
|
Uwaga: Zanim uruchomisz program, przeczytaj wstęp do tego artykułu, w którym wyjaśniamy funkcje tych programów oraz sposób korzystania z nich. |
| Program odczytuje
definicję grafu, tworzy macierz sąsiedztwa
i przechodzi ten graf algorytmem BFS poczynając od wierzchołka
|
|
Przykładowe dane (od teraz
wierzchołki będziemy oznaczać tylko numerami):
|
Pascal// BFS-macierz sąsiedztwa
// Data: 23.07.2013
// (C)2013 mgr Jerzy Wałaszek
//---------------------------
program bfs_adj;
// Typy dla dynamicznej
// macierzy i kolejki
type
// Wiersz
nptr = array of byte;
// Cała macierz
mptr = array of nptr;
PSLel = ^SLel;
SLel = record
next : PSLel;
Data: integer;
end;
// Zmienne globalne
var
// Liczba wierzchołków
n : integer;
// Macierz sąsiedztwa
A : mptr;
// Tablica odwiedzin
vs : array of boolean;
// Procedura przejścia wszerz
//---------------------------
procedure BFS(v : integer);
var
i : integer;
// Kolejka
q, head, tail : PSLel;
begin
// W kolejce umieszczamy v
new(q);
q^.next := nil;
q^.Data:= v;
head := q; tail := q;
// Wierzchołek v oznaczamy
// jako odwiedzony
vs[v] := true;
while head <> nil do
begin
// Odczytujemy v z kolejki
v := head^.data;
// Usuwamy z kolejki odczytane v
q := head;
head := head^.next;
if head = nil then tail := nil;
dispose(q);
write(v:3);
for i := 0 to n-1 do
if (A[v][i] = 1) and
(vs [i] = false) then
begin
// W kolejce umieszczamy
// nieodwiedzonych sąsiadów
new(q);
q^.next := nil;
q^.Data:= i;
if tail = nil then head := q
else tail^.next := q;
tail := q;
// i oznaczamy ich
// jako odwiedzonych
vs[i] := true;
end;
end;
end;
// **********************
// *** PROGRAM GŁÓWNY ***
// **********************
var
m, i, j, v1, v2 : integer;
begin
// Czytamy liczbę wierzchołków
// i krawędzi
read(n, m);
// Tworzymy tablicę wskaźników
SetLength(A, n);
// Tworzymy tablicę odwiedzin
SetLength(vs, n);
for i := 0 to n-1 do
// Tworzymy wiersze
SetLength(A[i], n);
// Macierz wypełniamy zerami
for i := 0 to n-1 do
begin
// Zerujemy tablicę odwiedzin
vs[i] := false;
for j := 0 to n-1 do
A[i][j] := 0;
end;
// Odczytujemy kolejne
// definicje krawędzi
for i := 1 to m do
begin
// Wierzchołek startowy
// i końcowy krawędzi
read(v1, v2);
// Krawędź v1->v2 obecna
A[v1][v2] := 1;
end;
writeln;
// Przechodzimy graf wszerz
BFS(0);
// Usuwamy macierz
for i := 0 to n-1 do
SetLength(A[i], 0);
SetLength(A, 0);
SetLength(vs, 0);
writeln;
end.
|
// BFS-macierz sąsiedztwa
// Data: 23.07.2013
// (C)2013 mgr Jerzy Wałaszek
//---------------------------
#include <iostream>
#include <iomanip>
using namespace std;
// Typ elementów listy dla kolejki
struct SLel
{
SLel * next;
int data;
};
// Zmienne globalne
// Liczba wierzchołków
int n;
// Macierz sąsiedztwa
char ** A;
// Tablica odwiedzin
bool * vs;
// Procedura przejścia wszerz
//---------------------------
void BFS(int v)
{
int i;
// Kolejka
SLel *q, *head, *tail;
// W kolejce umieszczamy v
q = new SLel;
q->next = NULL;
q->data = v;
head = tail = q;
// Wierzchołek v oznaczamy
// jako odwiedzony
vs[v] = true;
while(head)
{
// Odczytujemy v z kolejki
v = head->data;
// Usuwamy z kolejki odczytane v
q = head;
head = head->next;
if(!head) tail = NULL;
delete q;
cout << setw(3) << v;
for(i = 0; i < n; i++)
if((A[v][i] == 1) &&
!vs[i])
{
// W kolejce umieszczamy
// nieodwiedzonych sąsiadów
q = new SLel;
q->next = NULL;
q->data = i;
if(!tail) head = q;
else tail->next = q;
tail = q;
// i oznaczamy ich
// jako odwiedzonych
vs[i] = true;
}
}
}
// **********************
// *** PROGRAM GŁÓWNY ***
// **********************
int main()
{
int m, i, j, v1, v2;
// Czytamy liczbę wierzchołków
// i krawędzi
cin >> n >> m;
// Tworzymy tablicę wskaźników
A = new char * [n];
// Tworzymy tablicę odwiedzin
vs = new bool [n];
for(i = 0; i < n; i++)
// Tworzymy wiersze
A[i] = new char [n];
// Macierz wypełniamy zerami
for(i = 0; i < n; i++)
{
// Zerujemy tablicę odwiedzin
vs[i] = false;
for(j = 0; j < n; j++)
A[i][j] = 0;
}
// Odczytujemy kolejne
// definicje krawędzi
for(i = 0; i < m; i++)
{
// Wierzchołek startowy
// i końcowy krawędzi
cin >> v1 >> v2;
// Krawędź v1->v2 obecna
A[v1][v2] = 1;
}
cout << endl;
// Przechodzimy graf wszerz
BFS(0);
// Usuwamy macierz
for(i = 0; i < n; i++)
delete A[i];
delete [] A;
delete [] vs;
cout << endl;
return 0;
}
|
Basic' BFS-macierz sąsiedztwa
' Data: 23.07.2013
' (C)2013 mgr Jerzy Wałaszek
'---------------------------
' Typ elementów listy dla kolejki
Type SLel
next As SLel Ptr
data As Integer
End Type
' Zmienne globalne
' Liczba wierzchołków
Dim Shared As Integer n
' Macierz sąsiedztwa
Dim Shared As Byte Ptr Ptr A
' Tablica odwiedzin
Dim Shared As Byte Ptr vs
' Procedura przejścia wszerz
'---------------------------
Sub BFS(ByVal v As Integer)
Dim As Integer i
' Kolejka
Dim As SLel Ptr q, head, tail
' W kolejce umieszczamy v
q = new SLel
q->next = 0
q->data = v
head = q: tail = q
' Wierzchołek v oznaczamy
' jako odwiedzony
vs[v] = 1
While head
' Odczytujemy v z kolejki
v = head->Data
' Usuwamy z kolejki
' odczytane v
q = head
head = head->Next
If head = 0 Then tail = 0
delete q
Print Using "###";v;
For i = 0 To n-1
if (A[v][i] = 1) AndAlso _
(vs[i] = 0) Then
' W kolejce umieszczamy
' nieodwiedzonych sąsiadów
q = new SLel
q->next = 0
q->data = i
If tail = 0 Then
head = q
Else
tail->next = q
End If
tail = q
' i oznaczamy ich
' jako odwiedzonych
vs[i] = 1
End If
Next
Wend
End Sub
' **********************
' *** PROGRAM GŁÓWNY ***
' **********************
Dim As Integer m, i, j, v1, v2
Open Cons For Input As #1
' Czytamy liczbę wierzchołków
' i krawędzi
Input #1, n, m
' Tworzymy tablicę wskaźników
A = New Byte Ptr [n]
' Tworzymy tablicę odwiedzin
vs = New Byte [n]
For i = 0 To n-1
' Tworzymy wiersze
A[i] = New Byte [n]
Next
' Macierz wypełniamy zerami
For i = 0 To n-1
' Zerujemy tablicę odwiedzin
vs[i] = 0
For j = 0 To n-1
A[i][j] = 0
Next
Next
' Odczytujemy kolejne
definicje krawędzi
For i = 1 To m
' Wierzchołek startowy
' i końcowy krawędzi
Input #1, v1, v2
' Krawędź v1->v2 obecna
A[v1][v2] = 1
Next
Close #1
Print
' Przechodzimy graf wszerz
BFS (0)
' Usuwamy macierz
For i = 0 To n-1
Delete A[i]
Next
Delete [] A
Delete [] vs
Print
End
|
Python
(dodatek)# BFS-macierz sąsiedztwa
# Data: 8.12.2024
# (C)2024 mgr Jerzy Wałaszek
#---------------------------
# Klasa elementów listy dla kolejki
class SLel:
def __ini__(self):
self.next = None
self.data = 0
# Procedura przejścia wszerz
#---------------------------
def bfs(a,vt,n,v):
# Kolejka
head = None
tail = None
# W kolejce umieszczamy v
q = SLel()
q.next = None
q.data = v
head = q
tail = q
# Wierzchołek v oznaczamy jako odwiedzony
vt[v] = True
while head:
# Odczytujemy v z kolejki
v = head.data
# Usuwamy z kolejki odczytane v
q = head
head = head.next
if not head: tail = None
del q
print("%3d" % v, end="")
for i in range(n):
if (a[v][i] == 1) and \
not vs[i]:
# W kolejce umieszczamy
# nieodwiedzonych sąsiadów
q = SLel()
q.next = None
q.data = i
if not tail:
head = q
else:
tail.next = q
tail = q
# i oznaczamy ich jako odwiedzonych
vt[i] = True
# **********************
# *** PROGRAM GŁÓWNY ***
# **********************
# Czytamy liczbę wierzchołków i krawędzi
x = input().split()
n = int(x[0])
m = int(x[1])
# Tworzymy tablicę wskaźników
a = []
# Tworzymy tablicę odwiedzin
vs = [False] * n
for i in range(n):
# Tworzymy wiersze
x = [0] * n
a.append(x)
# Odczytujemy kolejne definicje krawędzi
for i in range(m):
# Wierzchołek startowy i końcowy krawędzi
x = input().split()
v1 = int(x[0])
v2 = int(x[1])
# Krawędź v1.v2 obecna
a[v1][v2] = 1
print()
# Przechodzimy graf wszerz
bfs(a,vs,n,0)
# Usuwamy macierz
for i in range(n):
a[i] = None
del a, vs
print()
|
| Wynik: |
14 21 0 1 0 2 0 8 1 4 1 5 1 7 2 9 3 0 3 10 3 11 4 13 5 6 5 7 5 13 7 8 8 9 10 9 10 11 12 0 12 3 13 12 0 1 2 8 4 5 7 9 13 6 12 3 10 11 |
K01: Q.push(v) ; w kolejce umieszczamy numer wierzchołka startowego K02: vs[v] ← true ; i oznaczamy go jako odwiedzony K03: Dopóki Q.empty() = false, ; tutaj jest pętla główna algorytmu BFS wykonuj kroki K04…K12 K04: v ← Q.front() ; odczytujemy z kolejki numer wierzchołka K05: Q.pop() ; odczytany numer usuwamy z kolejki K06: Przetwórz wierzchołek v ; tutaj wykonujemy operacje na wierzchołku v K07: p ← A[v] ; początek listy sąsiedztwa K08: Dopóki p ≠ nil: ; przeglądamy listę sąsiedztwa wierzchołka v wykonuj kroki K09…K12 K09: Jeśli vs[p→v] = true, ; szukamy nieodwiedzonego sąsiada to następny obieg pętli K08 K10: Q.push(p→v) ; nieodwiedzonych sąsiadów umieszczamy w kolejce K11: vs[p→v] ← true ; i oznaczamy jako odwiedzonych K12: p ← (p→next) ; następny element listy sąsiedztwa K13: Zakończ
Podobnie jak w algorytmie DFS, reprezentacja grafu listami sąsiedztwa jest bardzo korzystna dla BFS, ponieważ nie są wykonywane puste przebiegi pętli wyszukującej sąsiadów.
|
Uwaga: Zanim uruchomisz program, przeczytaj wstęp do tego artykułu, w którym wyjaśniamy funkcje tych programów oraz sposób korzystania z nich. |
| Program odczytuje definicję grafu, tworzy macierz sąsiedztwa i przechodzi ten graf algorytmem BFS poczynając od wierzchołka o numerze 0. Program wyświetla numery kolejno odwiedzanych wierzchołków. Kolejka jest utworzona za pomocą listy jednokierunkowej. |
|
Przykładowe dane (od teraz
wierzchołki będziemy oznaczać tylko numerami):
|
Pascal// BFS-listy sąsiedztwa
// Data: 23.07.2013
// (C)2013 mgr Jerzy Wałaszek
//---------------------------
program bfs_adjl;
// Typy dla dynamicznej tablicy
// list sąsiedztwa i kolejki
type
PSLel = ^SLel;
SLel = record
next : PSLel;
v : integer;
end;
TList = array of PSLel;
// Zmienne globalne
var
// Liczba wierzchołków i krawędzi
n : integer;
// Tablica list sąsiedztwa
A : TList;
// Tablica odwiedzin
vs : array of boolean;
// Procedura przejścia wszerz
//---------------------------
procedure BFS(v : integer);
var
// Kolejka
p, q, head, tail : PSLel;
begin
// W kolejce umieszczamy v
new(q);
q^.next := nil;
q^.v := v;
head := q; tail := q;
// Wierzchołek v oznaczamy
// jako odwiedzony
vs[v] := true;
while head <> nil do
begin
// Odczytujemy v z kolejki
v := head^.v;
// Usuwamy z kolejki odczytane v
q := head;
head := head^.next;
if head = nil then tail := nil;
dispose(q);
write(v:3);
p := A[v];
while p <> nil do
begin
if vs[p^.v] = false then
begin
// W kolejce umieszczamy
// nieodwiedzonych sąsiadów
new(q);
q^.next := nil;
q^.v := p^.v;
if tail = nil then head := q
else tail^.next := q;
tail := q;
// i oznaczamy ich jako odwiedzonych
vs[p^.v] := true;
end;
p := p^.next;
end;
end;
end;
// **********************
// *** PROGRAM GŁÓWNY ***
// **********************
var
m, i, v1, v2 : integer;
p, r : PSLel;
begin
// Czytamy liczbę wierzchołków
// i krawędzi
read(n, m);
// Tworzymy tablicę
// list sąsiedztwa
SetLength(A, n);
// Tworzymy tablicę odwiedzin
SetLength(vs, n);
// Tablice wypełniamy
// pustymi listami
for i := 0 to n-1 do
begin
A[i] := nil;
vs[i] := false;
end;
// Odczytujemy kolejne
// definicje krawędzi
for i := 0 to m-1 do
begin
// Wierzchołek startowy
// i końcowy krawędzi
read(v1, v2);
// Tworzymy nowy element
new(p);
// Numerujemy go jako v2
p^.v := v2;
// Dodajemy go na początek
// listy A[v1]
p^.next := A[v1];
A[v1] := p;
end;
writeln;
// Przechodzimy graf wszerz
BFS(0);
// Usuwamy tablicę list sąsiedztwa
for i := 0 to n-1 do
begin
p := A[i];
while p <> nil do
begin
r := p;
p := p^.next;
dispose(r);
end;
end;
SetLength(A, 0);
SetLength(vs, 0);
writeln;
end.
|
// BFS-listy sąsiedztwa
// Data: 23.07.2013
// (C)2013 mgr Jerzy Wałaszek
//---------------------------
#include <iostream>
#include <iomanip>
using namespace std;
// Typy dla dynamicznej tablicy
// list sąsiedztwa i kolejki
struct SLel
{
SLel * next;
int v;
};
// Zmienne globalne
// Liczba wierzchołków
int n;
// Macierz sąsiedztwa
SLel ** A;
// Tablica odwiedzin
bool * vs;
// Procedura przejścia wszerz
//---------------------------
void BFS(int v)
{
// Kolejka
SLel *p, *q, *head, *tail;
// W kolejce umieszczamy v
q = new SLel;
q->next = NULL;
q->v = v;
head = tail = q;
// Wierzchołek v oznaczamy
// jako odwiedzony
vs[v] = true;
while(head)
{
// Odczytujemy v z kolejki
v = head->v;
// Usuwamy z kolejki odczytane v
q = head;
head = head->next;
if(!head) tail = NULL;
delete q;
cout << setw (3) << v;
for(p = A[v]; p; p = p->next)
if(!vs[p->v])
{
// W kolejce umieszczamy
// nieodwiedzonych sąsiadów
q = new SLel;
q->next = NULL;
q->v = p->v;
if(!tail) head = q;
else tail->next = q;
tail = q;
// i oznaczamy ich
// jako odwiedzonych
vs[p->v] = true;
}
}
}
// **********************
// *** PROGRAM GŁÓWNY ***
// **********************
int main()
{
int m, i, v1, v2;
SLel *p, *r;
// Czytamy liczbę wierzchołków
// i krawędzi
cin >> n >> m;
// Tworzymy tablicę list sąsiedztwa
A = new SLel * [n];
// Tworzymy tablicę odwiedzin
vs = new bool [n];
// Tablicę wypełniamy pustymi listami
for(i = 0; i < n; i++)
{
A[i] = NULL;
vs[i] = false;
}
// Odczytujemy kolejne
// definicje krawędzi
for(i = 0; i < m; i++)
{
// Wierzchołek startowy
// i końcowy krawędzi
cin >> v1 >> v2;
// Tworzymy nowy element
p = new SLel;
// Numerujemy go jako v2
p->v = v2;
// Dodajemy go na początek
// listy A[v1]
p->next = A[v1];
A[v1] = p;
}
cout << endl;
// Przechodzimy graf wszerz
BFS(0);
// Usuwamy tablicę
// list sąsiedztwa
for(i = 0; i < n; i++)
{
p = A[i];
while(p)
{
r = p;
p = p->next;
delete r;
}
}
delete [] A;
delete [] vs;
cout << endl;
return 0;
}
|
Basic' BFS-listy sąsiedztwa
' Data: 23.07.2013
' (C)2013 mgr Jerzy Wałaszek
'---------------------------
' Typy dla dynamicznej tablicy
' list sąsiedztwa i kolejki
Type SLel
next As SLel Ptr
v As Integer
End Type
' Zmienne globalne
' Liczba wierzchołków
Dim Shared As Integer n
' Tablica list sąsiedztwa
Dim Shared As SLel Ptr Ptr A
' Tablica odwiedzin
Dim Shared As Byte Ptr vs
' Procedura przejścia wszerz
'---------------------------
sub BFS (ByVal v As Integer)
' Kolejka
Dim As SLel Ptr p, q, head, tail
' W kolejce umieszczamy v
q = new SLel
q->next = 0
q->v = v
head = q: tail = q
' Wierzchołek v oznaczamy jako odwiedzony
vs[v] = 1
While head
' Odczytujemy v z kolejki
v = head->v
' Usuwamy z kolejki odczytane v
q = head
head = head->Next
If head = 0 Then tail = 0
delete q
Print Using "###";v;
p = A[v]
while p <> 0
If vs[p->v] = 0 Then
' W kolejce umieszczamy
' nieodwiedzonych sąsiadów
q = new SLel
q->next = 0
q->v = p->v
If tail = 0 Then
head = q
Else
tail->next = q
End If
tail = q
' Wierzchołek v oznaczamy
' jako odwiedzony
vs[p->v] = 1
End If
p = p->Next
Wend
Wend
End Sub
' **********************
' *** PROGRAM GŁÓWNY ***
' **********************
Dim As Integer m, i, v1, v2
Dim As SLel Ptr p, r
Open Cons For Input As #1
' Czytamy liczbę wierzchołków i krawędzi
Input #1, n, m
' Tworzymy tablicę list sąsiedztwa
A = new SLel Ptr [n]
' Tworzymy tablicę odwiedzin
vs = New Byte [n]
' Tablicę wypełniamy pustymi listami
For i = 0 To n-1
A[i] = 0
vs[i] = 0
Next
' Odczytujemy kolejne definicje krawędzi
For i = 0 To m -1
' Wierzchołek startowy i końcowy krawędzi
Input #1, v1, v2
' Tworzymy nowy element
p = new SLel
' Numerujemy go jako v2
p->v = v2
' Dodajemy go na początek listy A[v1]
p->next = A[v1]
A[v1] = p
Next
Close #1
Print
' Przechodzimy graf wszerz
BFS(0)
' Usuwamy tablicę list sąsiedztwa
For i = 0 To n-1
p = A[i]
While p
r = p
p = p->Next
Delete r
Wend
Next
Delete [] A
Delete [] vs
Print
End
|
Python
(dodatek)# BFS-listy sąsiedztwa
# Data: 10.12.2024
# (C)2024 mgr Jerzy Wałaszek
#---------------------------
# Klasa dla dynamicznej tablicy
# list sąsiedztwa i kolejki
class SLel:
def __init__(self):
self.next = None
self.v = 0
# Procedura przejścia wszerz
#---------------------------
def bfs(a,vt,n,v):
# W kolejce umieszczamy v
q = SLel()
q.v = v
head = q
tail = q
# Wierzchołek v oznaczamy jako odwiedzony
vt[v] = True
while head:
# Odczytujemy v z kolejki
v = head.v
# Usuwamy z kolejki odczytane v
q = head
head = head.next
if not head: tail = None
del q
print("%3d" % v, end="")
p = a[v]
while p:
if not vt[p.v]:
# W kolejce umieszczamy
# nieodwiedzonych sąsiadów
q = SLel()
q.v = p.v
if not tail:
head = q
else:
tail.next = q
tail = q
# Wierzchołek v oznaczamy
# jako odwiedzony
vt[p.v] = True
p = p.next
# **********************
# *** PROGRAM GŁÓWNY ***
# **********************
# Czytamy liczbę wierzchołków i krawędzi
x = input().split()
n = int(x[0])
m = int(x[1])
# Tworzymy tablicę odwiedzin
vs = [False] * n
# Tworzymy tablicę list sąsiedztwa
a = [None] * n
# Odczytujemy kolejne definicje krawędzi
for i in range(m):
# Wierzchołek startowy i końcowy krawędzi
x = input().split()
v1 = int(x[0])
v2 = int(x[1])
# Tworzymy nowy element
p = SLel()
# Numerujemy go jako v2
p.v = v2
# Dodajemy go na początek listy A[v1]
p.next = a[v1]
a[v1] = p
print()
# Przechodzimy graf wszerz
bfs(a,vs,n,0)
# Usuwamy tablicę list sąsiedztwa
for i in range(n):
while a[i]:
a[i] = a[i].next
del a, vs
print()
|
| Wynik: |
14 21 0 1 0 2 0 8 1 4 1 5 1 7 2 9 3 0 3 10 3 11 4 13 5 6 5 7 5 13 7 8 8 9 10 9 10 11 12 0 12 3 13 12 0 8 2 1 9 7 5 4 13 6 12 3 11 10 |
![]() |
Zespół Przedmiotowy Chemii-Fizyki-Informatyki w I Liceum Ogólnokształcącym im. Kazimierza Brodzińskiego w Tarnowie ul. Piłsudskiego 4 ©2026 mgr Jerzy Wałaszek |
Materiały tylko do użytku dydaktycznego. Ich kopiowanie i powielanie jest dozwolone pod warunkiem podania źródła oraz niepobierania za to pieniędzy.
Pytania proszę przesyłać na adres email:
Serwis wykorzystuje pliki cookies. Jeśli nie chcesz ich otrzymywać, zablokuj je w swojej przeglądarce.
Informacje dodatkowe.