Sắp thứ tự dãy số 5, 3, 1, 9, 8, 2, 11 bằng
heapsort
5
9
3
1
5
1
3
9
9
8
1
8
3
2
5
3
5
1
11
8
3
CuuDuongThanCong.com
9
5
1
2
/>
1
9
8
8
2
5
3
5
1
2
11
3
1
9
11
5
3
3
2
1
8
1
2
9
11
8
9
11
5
2
1
1
3
2
3
8
5
CuuDuongThanCong.com
9
11
5
8
9
11
/>
2
Duyệt theo chiều sâu trước – không đệ quy
procedure list-dfs;
var id, k: integer; val: array[1..max V] of integer;
procedure visit(k: integer);
var t: link;
begin
push(k);
repeat
k: = pop; id:= id + 1; val[k]: = id; /* change the status of k to “visited” */
t =: adj[k];
/* find the neighbors of the vertex k */.
while t <> z do
begin
if val[t .v] = 0 then
begin
push(t .v); val[t .v]: = -1 /* change the status of t .v to “ready” */
end
else if val[t .v] = -1 then shift t .v to the top of the stack;
t: = t .next
end
until stackempty
end;
CuuDuongThanCong.com
/>
3
begin
id: = 0; stackinit;
for k: = 1 to V do val[k]: = 0; /* initialize the
status of all vertices */
for k: = 1 to V do
if val[k] = 0 then visit(k)
end;
Với giải thuật không đệ quy, ta cần dùng một stack được gọi
là ready stack.
Ghi chú:
val[k] = 0 nếu đỉnh k là “chưa được viếng thăm”,
val[k] = -1 nếu đỉnh k đang ở trong ready stack
val[k] là một trị dương nếu đỉnh k đã được viếng thăm.
CuuDuongThanCong.com
/>
4
Một thí dụ
A
H
B
C
D
I
G
E
J
K
F
L
M
Hình 4.1a Một đồ thị thí dụ
CuuDuongThanCong.com
/>
5
G E D
B B F F
C C B B B
A F F C C C
M
L L
C H I J K K K
Hình 4.3b Nội dung của stack khi thực hiện duyệt theo chiều sâu
trước
CuuDuongThanCong.com
/>
6
Problem 4. Các thành phần liên thông của 1 đồ thị
Depth-first-search
procedure visit(k: integer);
var t: link;
begin
push(k);
repeat
k: = pop; id:= id + 1; val[k]: = id; /* change the status of k to “visited” */
write(name(k)); /* print out the name of the visited vertex */
t =: adj[k];
/* find the neighbors of the vertex k */.
while t <> z do
begin
if val[t .v] = 0 then
begin
push(t .v); val[t .v]: = -1 /* change the status of t .v to “ready” */
end
else if val[t .v] = -1 then shift t .v to the top of the stack;
t: = t .next
end
until stackempty
end;
CuuDuongThanCong.com
/>
7
begin
id: = 0;
for k: = 1 to V do val[k]: = 0; /*initialize the status of all vetices */
for k: = 1 to V do
begin
if val[k] = 0 then visit(k);
/* end of one connected component*/
writeln; writeln
end;
end;
Mỗi lần quay về sau một lượt gọi visit() là vừa hoàn tất sự duyệt qua một thành
phần liên thông trong đồ thị.
CuuDuongThanCong.com
/>
8
Bài tập: TreeSort
Procedure Tree-sort(T)
let T be an empty binary search trê
for i := 1 to n do
TreeInsert(T, A[i]);
InOrder-Tree-Traversal(T);
Giải thuật sắp thứ tự bao gồm hai bước: tạo cây và duyệt
cây theo thứ tự in-order.
Hãy phân tích độ phức tạp của giải thuật Tree-sort trong hai
trường hợp tốt nhất và xấu nhất.
CuuDuongThanCong.com
/>
9
Procedure Inorder-Tree-Traversal(T:link)
begin
if T <> z then
begin
Inorder-Tree-Traversal(T .l);
visit(T);
Inorder-Tree-Traversal(T .r);
end
end
Nếu độ phức tạp của giải thuật duyệt cây theo inorder dựa vào số lần
gọi đệ quy hàm Inorder-Tree-Traversal, thì độ phức nạp này là C(n) =
2n + 1 = O(n) với n là số nút trong cây.
Như vậy độ phức tạp của giải thuật Tree-Sort chủ yếu nằm ở giai đoạn
tạo cây nhị phân tìm kiếm.
CuuDuongThanCong.com
/>
10
Độ phức tạp của giai đoạn tạo cây
Trường hợp tốt nhất: khi cây nhị phân được tạo ra
luôn được cân bằng ở mọi thao tác thêm vào. Do đó
độ phức tạp của vịng for tạo cây là O(nlgn) vì mỗi
thao tác thêm nút vào cây cân bằng ln ít hơn lg(n)
lần so sánh.
Trong trường hợp xấu nhất: cây nhị phân tạo ra suy
biến thành một danh sách tuyến tính. Khi đó số lần
so sánh khi tạo cây gồm n nút sẽ là:
1 + 2 + …+ + (n-1) = n(n-1)/2
Như vập độ phức tạp của giai đoạn tạo cây trong
trường hợp này sẽ là: O(n2).
CuuDuongThanCong.com
/>
11
Tóm lại:
Trường hợp xấu nhất: độ phức tạp của Treesort là O(n2) khi cây có dạng xâu tuyến tính
được tạo ra.
Trường hợp tốt nhất: độ phức tạp của Treesort là O(nlgn) khi cây có dạng cây cân bằng
được tạo ra.
CuuDuongThanCong.com
/>
12