Chu trình đơn trong đồ thịGđi qua mỗi cạnh của đồ thịđúng một lần được gọi là chu trình Euler. Đường đi đơn trong G đi qua mỗi cạnh của nó đúng một lần được gọi là đường
đi Euler. Đồ thịđược gọi là đồ thị Euler nếu nó có chu trình Euler. Đồ thị có đường đi Euler
được gọi là nửa Euler.
Rõ ràng, mọi đồ thị Euler đều là nửa Euler nhưng điều ngược lại không đúng.
Ví dụ 1. Xét các đồ thị G1, G2, G3 trong hình 5.12. a b a b a b e e d c d c c d e G1 G2 G3 Hình 5.12. Đồ thị vô hướng G1, G2, G3.
Đồ thị G1 là đồ thị Euler vì nó có chu trình Euler a, e, c, d, e, b, a. Đồ thị G3 không có chu trình Euler nhưng chứa đường đi Euler a, c, d, e, b, d, a, b vì thế G3 là nửa Euler. G2 không có chu trình Euler cũng nhưđường đi Euler.
Định lý. Đồ thị vô hướng liên thông G=<V, E> là đồ thị Euler khi và chỉ khi mọi
đỉnh của Gđều có bậc chẵn. Đồ thị vô hướng liên thông G=<V, E> là đồ thị nửa Euler khi và chỉ khi nó không có quá hai đỉnh bậc lẻ.
Để tìm một chu trình Euler, ta thực hiện theo thuật toán sau:
Tạo một mảng CE để ghi đường đi và một stack để xếp các đỉnh ta sẽ xét. Xếp vào đó một đỉnh tuỳ ý u nào đó của đồ thị, nghĩa là đỉnh u sẽđược xét
đầu tiên.
Xét đỉnh trên cùng của ngăn xếp, giả sửđỉnh đó là đỉnh v; và thực hiện:
9 Nếu v là đỉnh cô lập thì lấy v khỏi ngăn xếp và đưa vào CE;
9 Nếu v là liên thông với đỉnh x thì xếp x vào ngăn xếp sau đó xoá bỏ cạnh (v, x);
Quay lại bước 2 cho tới khi ngăn xếp rỗng thì dừng. Kết quảđường đi Euler
được chứa trong CE theo thứ tự ngược lại.
Thủ tục Euler_Cycle sau sẽ cho phép ta tìm chu trình Euler.
void Euler_Cycle(int u){ Stack=φ; CE=φ;
u=>Stack; { nạp u vào stack}; while (Stack≠φ) {
x= top(Stack); { x là phần tửđầu stack } if (ke(x) ≠φ) {
y = Đỉnh đầu trong danh sách ke(x); Stack<=y; { nạp y vào Stack}; Ke(x) = Ke(x) \{y};
Ke(y) = Ke(y)\{x}; {loại cạnh (x,y) khỏi đồ thị};
} else { x<= Stack; {lấy x ra khỏi stack}; CE <=x; { nạp x vào CE;} } }
Ví dụ. Tìm chu trình Euler trong hình 5.13.
a b
4
1 2 3 5 6 7
f 8 c 9 d 10 e
Các bước thực hiện theo thuật toán sẽ cho ta kết quả sau:
Bước Giá trị trong stack Giá trị trong CE Cạnh còn lại
1 F 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 2 f, a 2, 3, 4, 5, 6, 7, 8, 9, 10 3 f, a, c 3, 4, 5, 6, 7, 8, 9, 10 4 f,a,c,f 3, 4, 5, 6, 7, 9, 10 5 f, a, c f 3, 4, 5, 6, 7, 9, 10 6 f, a, c, b f 3, 4, 6, 7, 9, 10 7 f, a, c, b, d f 3, 4, 7, 9, 10 8 f, a, c, b, d,c f 3, 4, 7, 10 9 f, a, c, b, d f, c 3, 4, 7, 10 10 f, a, c, b, d, e f, c 3, 4, 7 11 f, a, c, b, d, e, b f, c 3, 4 12 f, a, c, b, d, e, b, a f, c 3 13 f, a, c, b, d, e, b, a, d f, c 14 f, a, c, b, d, e, b, a f, c, d 15 f, a, c, b, d, e, b f,c,d,a 16 f, a, c, b, d, e f,c,d,a,b 17 f, a, c, b, d f,c,d,a,b,e 18 f, a, c, b f,c,d,a,b,e,d 19 f, a, c f,c,d,a,b,e,d,b 20 f, a f,c,d,a,b,e,d,b,c 21 f f,c,d,a,b,e,d,b,c,a 22 f,c,d,a,b,e,d,b,c,a,f
Một đồ thị không có chu trình Euler nhưng vẫn có thể có đường đi Euler. Khi đó, đồ
thị có đúng hai đỉnh bậc lẻ, tức là tổng các số cạnh xuất phát từ một trong hai đỉnh đó là số
lẻ. Một đường đi Euler phải xuất phát từ một trong hai đỉnh đó và kết thúc ởđỉnh kia. Như
vậy, thuật toán tìm đường đi Euler chỉ khác với thuật toán tìm chu trình Euler ở chỗ ta phải xác định điểm xuất phát của đường đi.
Để tìm tất cả các đường đi Euler của một đồ thị n đỉnh, m cạnh, ta có thể dùng kỹ
thuật đệ qui như sau:
Bước 1. Tạo mảng b có độ dài m + 1 như một ngăn xếp chứa đường đi. Đặt b[0]=1, i=1 (xét đỉnh thứ nhất của đường đi);
Bước 2. Lần lượt cho b[i] các giá trị là đỉnh kề với b[i-1] mà cạnh (b[i-1],b[i])
không trùng với những cạnh đã dùng từ b[0] đến b[i-1]. Với mỗi giá trị của b[i], ta kiểm tra:
9 Nếu i<m thì tăng i lên 1đơn vị (xét đỉnh tiếp theo) và quay lại bước 2.