Final Sol 1 Đại học Quốc Gia TP Hồ Chí Minh Trường đại học Bách Khoa Khoa Khoa học & Kỹ thuật Máy tính Bộ môn Khoa học Máy tính ĐỀ THI CUỐI HỌC KỲ 1 Năm học 2010 – 2011 Môn Cấu trúc dữ liệu & Giải thu[.]
Trang 1Đại học Quốc Gia TP Hồ Chí Minh
Trường đại học Bách Khoa
Khoa: Khoa học & Kỹ thuật Máy tính
Bộ môn: Khoa học Máy tính
Năm học: 2010 – 2011
Môn: Cấu trúc dữ liệu & Giải thuật
MSMH: 503001 Ngày thi: 20/01/2011 - Thời gian: 120 phút
(Được sử dụng tài liệu)
Lưu ý: Đề thi gồm 4 câu với thang điểm 11/10
Câu 1: (2.5 điểm)
Cho một dãy gồm 11 số như sau: 10, 26, 9, 3, 21, 17, 30, 28, 91, 29, 72
a (1.5 điểm) Cây AVL được xây dựng dựa trên chuỗi số này, giả sử các số được nhập vào khi xây dựng cây đúng theo thứ tự trên Vẽ cây AVL trong các trường hợp sau:
• Sau khi chèn (insert) thành công phần tử 17
• Sau khi chèn thành công phần tử 91
• Sau khi chèn thành công phần tử 72
b (1 điểm) Giả sử cây AVL được xây dựng ở câu a lần lượt bị xóa các phần tử sau: 9, 3,
29, 26 Vẽ lại các cây AVL sau khi từng phần tử trên bị xóa khỏi cây
Giải:
a Insert 17
Insert 91
10
9
3
21
10
9
3
28
Trang 2Insert 72
b Delete 9
Delete 3
Delete 29
28
10
9
30
72
21
3
28
10
3
30
72
21
28
21
10
30
72
26
17
28
21
10
72
26
17
Trang 3Delete 26
Câu 2: (3 điểm)
Ta ký hiệu L(H) là dạng trình bày của max heap H dưới dạng dãy
Ví dụ: Một dãy số ban đầu như sau: (1, 2, 3), sau khi xây dựng thành heap HT, thì L(HT) =
(3, 1, 2)
a (1 điểm) Với dãy số ban đầu gồm 10 số như sau: (17, 26, 10, 9, 3, 21, 30, 28, 91, 72),
ta xây dựng thành heap H1 Giả sử các số được đưa vào H1 theo đúng thứ tự trên Cho
biết L(H 1)
b (0.5 điểm) Sau khi loại bỏ 3 phần tử khỏi H1, ta được H2 Cho biết L(H2)
c (1.5 điểm) Trình bày một giải thuật sử dụng heap để sắp xếp lại một dãy số với yêu cầu như sau:
Input: Dãy số a có n phần tử từ a[1] đến a[n]
Output: Dãy số a đã được sắp xếp theo thứ tự như sau: các số chẵn sắp trước, các số lẻ
sắp sau, các số chẵn được sắp xếp từ nhỏ đến lớn, các số lẻ được sắp từ lớn đến nhỏ
Ví dụ: Nếu a là (7, 4, 2, 1, 16, 19, 23, 24), sau khi sắp xếp sẽ là (2, 4, 16, 24, 23, 19, 7, 1)
Do số lượng phần tử n của dãy a là khá lớn, giải thuật sắp xếp này không được khai báo
thêm biến phụ có dung lượng lưu trữ tương đương với n (ví dụ như khai báo một dãy
tạm có độ lớn là n/10 vì n/10 và n là tương đương)
Các phương thức cơ bản của heap được cho như trong bộ slide lý thuyết của môn học Tuy nhiên, khi sử dụng các phương thức này sinh viên phải ghi rõ là phương thức của
max heap hay min heap Ví dụ khi sử dụng phương thức ReheapUp của max heap thì tên phướng thức sẽ là ReMaxheapUp, còn tên phương thức này của min heap sẽ là ReMinheapUp
Giải:
a L(H1) = (91, 72, 26, 28, 30, 10, 21, 9, 17, 3)
28
17
10
72
21
91
72
28
26
3
30
9 17
Trang 4b L(H2) = (28, 17, 26, 9, 3, 10, 21)
c void sort(ref a[] <Array>)
1 i = 1
2 last_odd = 0 // chi so phan cach giua cac so chan va so le
3 n = sizeof(a)
4 loop(i <= n)
1 if(a[i] mod 2 != 0)
1 last_odd = last_odd + 1
2 swap(a[last_odd], a[i])
2 i = i + 1
5 if(last_odd > 1) // sap xep tang dan cac so le
1 position = last_odd/2
2 loop(position > 0)
1 ReMaxheapDown(a, position, last_odd)
2 position = position – 1
3 last = last_odd
4 loop(last > 0)
1 swap(a[1], a[last])
2 last = last – 1
3 ReMaxheapDown(a, 1, last)
6 i = 1
7 j = n
8 loop(i < j) // sau vong lap nay cac so le voi thu tu giam dan
// duoc chuyen ve cuoi day
1 swap(a[i], a[j])
2 i = i + 1
3 j = j – 1
9 last_even = n – last_odd
10.if(last_even > 1) // sap xep tang dan cac so chan
1 position = last_even/2
2 loop(position > 0)
1 ReMaxheapDown(a, position, last_even)
2 position = position – 1
3 last = last_even
4 loop(last > 0)
1 swap(a[1], a[last])
2 last = last – 1
3 ReMaxheapDown(a, 1, last)
end sort
Câu 3: (3.5 điểm)
Có 6 thành phố có tên A, B, C, D, E, F Người ta dự định xây dựng đường giao thông nối giữa các thành phố sao cho giữa 4 thành phố bất kỳ thì luôn có ít nhất một thành phố có
đường giao thông trực tiếp đến 3 thành phố còn lại
28
17
9
26
3
Trang 5a (0.5 điểm) Vẽ một đồ thị vô hướng thỏa mãn yêu cầu trên với A, B, C, D, E, F là 6
đỉnh của đồ thị, đường giao thông trực tiếp giữa 2 thành phố là cạnh nối giữa 2 đỉnh
b (0.5 điểm) Chuyển đồ thị trong câu a thành đồ thị có hướng theo quy tắc sau: cạnh nối
vô hướng (x,y) sẽ chuyển thành cạnh nối có hướng từ x đến y nếu x đứng trước y trong
bảng chữ cái Trình bày lại đồ thị này dưới dạng bảng kề (adjacency table)
c (0.5 điểm) Chứng minh đồ thị trong câu b không bao giờ xuất hiện chu trình
d (1 điểm) Cho biết các topological order của đồ thị trong câu b tương ứng với các phương pháp depth-first ordering và breadth-first ordering
e (1 điểm) (bonus)
e1 Dành cho lớp thường: Với một đồ thị vô hướng n đỉnh cho trước, xác định số k lớn nhất sao cho giữa k đỉnh bất kỳ trên đồ thị thì luôn có ít nhất một đỉnh có cạnh nối
đến k-1 đỉnh còn lại Viết giải thuật để tính số k này
e2 Dành cho lớp KSTN (không cần làm câu e1): Bài toán được nêu trong câu e1 thuộc về lớp P hay NP? Vì sao?
Giải:
a
b
c Đồ thị có hướng trong câu b chỉ có đường đi từ đỉnh có thứ tự đứng trước đến đỉnh có thứ tự đứng sau trong bảng chữ cái mà không có đường đi ngược lại
d Cả hai phương pháp depth-first ordering và breadth-first ordering đều có chung topological order đối với đồ thị này: A, B, C, D, E, F
A
B
C
F
D
E
Trang 6e1 Ý tưởng: Cho k chạy từ n -> 1, mỗi lần lặp giảm k xuống 1 đơn vị
• Xét tất cả các tổ hợp chập k của n đỉnh xem trong từng tổ hợp này có tồn tại đỉnh
có cạnh nối đến k – 1 đỉnh còn lại hay không
• Nếu tất cả các tổ hợp đều thỏa mãn thì trả về số k
integer findK(val G <Graph>)
1 list <List <Vertex>>
2 k = G.numVertex
3 loop(k > 1)
1 index = 0
2 flag = true
3 loop(index + k <= G.numVertex AND flag == true)
1 recFind(k, index, list, G, flag)
2 index = index + 1
4 if(flag == true) return k
5 k = k – 1
4 return 1
end findK
void recFind(val k <integer>, val index <integer>,
ref list <List <Vertex>>, val G <Graph>, ref flag <boolean>)
1 list.addLast(G.a[index])
2 if(list.size() < k)
1 i = 1
2 loop(k – list.size() <= G.numVertex – (index + i)
AND flag == true)
1 recFind(k, index + i, list, G, flag)
2 i = i + 1
3 else
1 flag = checkTrue(list, G)
4 list.removeLast()
end recFind
boolean checkTrue(val list <List <Vertex>>, val G <Graph>)
1 i = 0
2 loop(i < list.size())
1 j = 0
2 loop(j < list.size())
1 if(i != j AND
NOT hasEdge(G, list.retrieve(i), list.retrieve(j))
1 break
2 j = j + 1
3 if(j == list.size()) return true
4 i = i + 1
3 return false
end checkTrue
e2 Bài toán được nêu trong câu e1 thuộc về lớp NP Tương ứng với giá trị k bất kỳ (1 <=
k <= n), ta dùng phương pháp vét cạn để xét tất cả các tổ hợp chập k của n đỉnh trong đồ thị xem trong từng tổ hợp k đỉnh như vậy có tồn tại đỉnh có cạnh nối đến k – 1 đỉnh còn lại hay không Chỉ khi nào tất cả các tổ hợp đều thỏa mãn yêu cầu thì giá trị k đó mới hợp
lệ Tuy nhiên, bài toán yêu cầu tìm số k lớn nhất có thể Do vậy, ta sẽ xét giá trị k ban đầu
Trang 7là n (giá trị lớn nhất có thể có của k), nếu giá trị hiện tại không thỏa mãn thì ta giảm giá trị của k xuống 1 đơn vị và tiếp tục xét tất cả các tổ hợp đỉnh với giá trị k mới này Quá trình lặp lại như vậy cho đến khi nào tìm được giá trị k thỏa mãn
Khi đó, độ phức tạp của bài toán trong trường hợp xấu nhất sẽ là:
1
( 1)
n k n k
C k k
=
−
Câu 4: (2 điểm)
Cho một dãy gồm 11 số như sau: 10, 26, 9, 3, 21, 17, 30, 28, 91, 29, 72
a (1 điểm) Xây dựng hai cây B-tree tương ứng với dãy số trên, với số bậc của hai cây này là 3 và 5 Giả sử thứ tự các phần tử được đưa vào cây tương ứng với thứ tự trên dãy
b (1 điểm) Vẽ lại hai cây B-Tree được xây dựng ở câu a sau khi xóa phần tử 21 ra khỏi hai cây này
Giải:
a B-Tree bậc 3
B-Tree bậc 5
b Xóa phần tử 21 ra khỏi cây B-Tree bậc 3
21
10, 26, 30
3, 9 17, 21 28, 29 72, 91
17
Trang 8Hoặc:
Xóa phần tử 21 ra khỏi cây B-Tree bậc 5
Hoặc:
Hết
26
26, 30
3, 9, 10, 17 28, 29 72, 91
10, 30
3, 9 17, 26, 28, 29 72, 91