You are on page 1of 11

ĐẠI HỌC QUỐC GIA HÀ NỘI

TRƯỜNG ĐẠI HỌC CÔNG NGHỆ

ĐỀ THI HỌC PHẦN CẤU TRÚC DỮ LIỆU VÀ GIẢI THUẬT


HỌC KỲ 1 NĂM HỌC 2021 – 2022 (Dành cho khung chương trình 4 tín chỉ)
Thời gian làm bài: 120 phút
Đề thi có 04 trang,
Đề dài, các câu tuy dài ngắn khác nhau nhưng đều có số điểm bằng nhau,
hãy cân nhắc để sắp xếp thứ tự ưu tiên khi làm bài
Sinh viên được phép sử dụng tài liệu giấy. Cán bộ coi thi không giải thích gì thêm

Câu 1.
Hãy cho biết độ phức tạp tính toán của các đoạn code sau theo hàm số của N:
a, b,
int count = 0; int count = 0;
for (int i = 0; i < N; i ++) for (int n = N; n > 0; n /= 2)
for(int j = 0; j < N; j++) for (int i = 0; i < n; i++)
count++; count ++;

Câu 2.
Biểu thức dạng trung tố E được lập thành từ các toán hạng là các số nguyên, các toán tử gồm các
phép toán +, –, *, / và các dấu mở ngoặc đơn, đóng ngoặc đơn. Biểu thức dạng hậu tố Ba Lan là
biểu thức các toán tử từ dạng trung tố được chuyển sang dạng hậu tố (Ví dụ: Biểu thức a b + là biểu
thức dạng hậu tố Ba Lan của biểu thức a + b)
Cho biểu thức dạng trung tố E = (5 – 3) + 2 * (20 + 3) – 7
Hãy minh họa từng bước việc sử dụng ngăn xếp để chuyển biểu thức E sang biểu thức PE dạng hậu
tố Ba Lan.

Câu 3.
Hãy nêu thuật toán cho một hàm phát hiện chu trình của danh sách liên kết. Hàm cần thỏa mãn các
điều kiện sau:
1. Tham số của hàm là con trỏ (hoặc tham chiếu) tới nút đầu danh sách.
2. Hàm trả về true nếu danh sách liên kết đó có đoạn nối thành vòng tròn, trả về false nếu
không có.
Thuật toán của bạn được sử dụng tất cả các cấu trúc dữ liệu có sẵn trong C++/Java hoặc không
dùng đến. Bạn sẽ được điểm càng cao nếu lượng bộ nhớ phải dùng đến càng thấp (thấp nhất là
hằng số).

Câu 4.
Hãy nêu thuật toán duyệt cây nhị phân tìm kiếm để in ra các khóa trên cây theo thứ tự giảm dần.

1
Câu 5.
a. Mô tả quá trình thêm các khóa sau và một hàng đợi ưu tiên C A E H D I B G F. Biết rằng
hàng đợi ưu tiên đó ban đầu rỗng và được cài bằng heap loại max
b. Lấy heap kết quả phần a, hãy vẽ kết quả sau khi thực hiện một lệnh delMax từ hàng đợi ưu
tiên.

Câu 6.
Cho dãy số A = {12, 2, 8, 5, 1, 6, 4, 15}. Hãy minh họa các bước thực hiện khi sắp xếp dãy số A
tăng dần bằng phương pháp sắp xếp nhanh (quicksort).

Câu 7.
Cho một bảng băm kích thước 11 và một hàm băm (hash function) h(x) = x mod 11. Bạn cần thêm
vào bảng băm chuỗi khóa sau theo đúng thứ tự đã cho: 12, 56, 4, 77, 122, 83, 44, 23, 20, 38, 55.
a. Theo bạn phương pháp xử lý xung đột (collision) nào là phù hợp cho bài toán này? Hãy giải thích
lý do.
b. Hãy trình bày quá trình chèn chuỗi khóa đã cho vào bảng băm bằng phương pháp mà bạn đã
chọn ở câu trên.

Câu 8.
a. Hãy vẽ cây nhị phân tìm kiếm (loại thường) mà bạn thu được sau khi thêm chuỗi khóa C B
A F G H D E (theo đúng thứ tự đó) vào một cây nhị phân tìm kiếm rỗng.
b. Hãy vẽ cây thu được sau khi xóa khóa C khỏi cây thu được từ phần a.
c. Hãy làm lại phần a nhưng sử dụng một cây tìm kiếm cân bằng. Hãy vẽ cây kết quả.

Câu 9.
Cho một đồ thị có hướng gồm 12 đỉnh và 18 cạnh liệt kê dưới đây
0⇾9, 0⇾5, 1⇾10, 2⇾8, 3⇾1, 4⇾5, 5⇾8, 9⇾1, 9⇾10,
4⇾2, 8⇾4, 7⇾4, 7⇾0, 5⇾0, 10⇾3, 6⇾3, 3⇾11, 10⇾6
a. Hãy vẽ biểu diễn danh sách kề của đồ thị. Các đình trong mỗi danh sách kề cần sắp xếp sẵn
theo thứ tự tăng dần. Thứ tự này sẽ được dùng cho phần b.
b. Hãy dùng thuật toán tìm kiếm theo chiều sâu (depth-first search) để thăm từng đỉnh của đồ
thị, xuất phát từ đỉnh 0, Hãy viết trình tự các đỉnh theo thứ tự được thăm theo thuật toán.

Câu 10.
Cho một đồ thị vô hướng gồm 8 đỉnh và 16 cạnh có trọng số được liệt kê dưới đây
0-1 0.28 1-3 0.16 2-3 0.58 3-5 0.26 4-5 0.36
0-4 0.32 1-4 0.19 2-5 0.40 3-6 0.38 4-7 0.29
0-6 0.35 1-5 0.34 2-6 0.93 5-7 0.17
1-6 0.37 2-7 0.52

2
Hãy sử dụng thuật toán Kruskal để tính cây bao trùm nhỏ nhất. Hãy liệt kê các cạnh trong cây bao
trùm nhỏ nhất lần lượt theo thứ tự tìm được.

Câu 11.
Cho một đồ thị có hướng gồm 8 đỉnh và 15 cạnh có trọng số cho dưới đây,
0⇾2 2.4 1⇾0 1.0 2⇾5 0.6 3⇾6 2.6 4⇾7 1.0
0⇾5 3.0 1⇾4 1.8 2⇾6 2.2 4⇾3 0.8 5⇾6 1.8
0⇾7 0.8 1⇾7 1.6 3⇾2 0.2 4⇾6 4.0 7⇾3 1.2
7⇾2 1.4
Hãy trình bày quá trình sử dụng thuật toán Dijkstra để tìm cây đường đi ngắn nhất xuất phát từ 1 tới
các đỉnh còn lại.

Câu 12.
Hãy nêu thuật toán để giải bài sau đây:
Input: một dãy số độ dài tối đa 1 triệu a0, a1, … aN.
Output: một dãy số b0, b1…bN. Trong đó bi là số đứng gần nhất bên phải ai trong dãy input mà có giá
trị nhỏ hơn ai. Hoặc là giá trị -1 nếu bên phải ai không có giá trị nào nhỏ hơn ai
Ví dụ:
Input: 7461963
Output: 4 1 1 -1 6 3 -1

Câu 13.
Một mạng lưới tình báo được tổ chức như sau: Mỗi điệp viên chỉ biết 01 cấp trên trực tiếp của mình
và là cấp trên của tối đa 02 điệp viên khác. Người đứng đầu mạng lưới tất nhiên không có cấp trên.
Mỗi lần cần lan truyền một mẩu tin thì một người sẽ truyền tin cho cấp trên trực tiếp và các thuộc
cấp của mình nếu có, và họ sẽ tiếp tục truyền tin theo cách đó. Giả sử thời gian cần thiết cho một
người nhận tin và truyền cho cấp trên và các thuộc cấp là 01 phút và tất cả đều luôn luôn sẵn sàng
nhận và truyền tin suốt 24 tiếng mỗi ngày.
Bài toán đặt ra là khi cần lan truyền một mẩu tin từ một điệp viên tới toàn bộ lưới thì sau tối đa bao
nhiêu phút toàn bộ các điệp viên đều nhận được mẩu tin đó.
Cho thiết kế sau của Spy. Hãy trình bày thuật toán (mã giả) cho hàm maxDelay trả về số phút tối đa
cần đến để truyền tin từ điệp viên bất kì đến toàn bộ lưới. Bạn có thể thêm hàm/biến thực thể vào
class Spy.

class Spy {
Spy boss, firstStaff, secondStaff;
}

long maxDelay(Spy head) {


//…
}

3
Câu 14.
Cho dãy các số nguyên A gồm các phần tử a0, a1, …, aN, (0 < N <2000). Một dãy con không giảm là
dãy: ai1, ai2, …, aik trong đó (0<= i1 < i2 <…< ik <=N) và ai1 <= ai2 <= …<=aik. Trong các dãy con
không giảm như vậy sẽ có dãy con có tổng các phần tử là lớn nhất.

Trình bày ý tưởng và các bước chính thuật toán tìm được giá trị tổng lớn nhất của các dãy con
không giảm nêu trên.

Ví dụ:
Input: 1 101 2 3 100 4 5
Output: 106
(Vì 106 = 1 + 2 + 3 + 100)

Hết

4
Đáp án

Câu 1.
Hãy cho biết độ phức tạp tính toán của các đoạn code sau theo hàm số của N:
A, b,
int count = 0; int count = 0;
for (int i = 0; i < N; i ++) for (int n = N; n > 0; n /= 2)
for(int j = 0; j < N; j++) for (int i = 0; i < n; i++)
count++; count ++;
N*N N + N/2 + N/4 + … + 0 = 2N
(bậc 2) (tuyến tính)

Câu 2.
Biểu thức dạng trung tố E được lập thành từ các toán hạng là các số nguyên, …
Bước Bước Bước Bước Bước Bước Bước Bước Bước Bước Bước
1 2 3 4 5 6 7 8 9 10 11

Trạng thái của ngăn xếp

) )

- * * * *

( ( + + + + + + -
PE = 5 3 – 2 20 3 + * + 7 –

Câu 3.
Hãy nêu thuật toán cho một hàm phát hiện chu trình của danh sách liên kết.
Cho 2 con trỏ p1, p2 bắt đầu từ head,
dùng vòng lặp, mỗi lần cho p1 nhảy 1 bước, p2 nhảy 2 bước.
Vòng lặp kết thúc khi gặp null hoặc khi p1 == p2
Gặp null nghĩa là không có chu trình.
Bộ nhớ phụ chỉ gồm 2 con trỏ nên là hằng số
Cách tồi hơn: dùng tập hợp cài bằng bảng băm để băm địa chỉ của nút (C++) hoặc hashcode của đối
tượng (Java). Độ phức tạp bộ nhớ: tuyến tính

5
Câu 4.
Hãy nêu thuật toán duyệt cây nhị phân tìm kiếm để duyệt các khóa trên cây theo thứ tự giảm dần.
Inorder traverse nhưng đổi thứ tự thành right, parent, left

Câu 5.
a. Mô tả quá trình thêm các khóa sau và một hàng đợi ưu tiên C A E H D I B G F. Biết rằng
hàng đợi ưu tiên đó ban đầu rỗng và được cài bằng heap loại max

C
CA
EAC
HECA
HECAD
IEHADC
IEHADCB
IGHEDCBA
IGHEDCBAF
IGHFDCBAE

b. Lấy heap kết quả phần a, hãy vẽ kết quả sau khi thực hiện một lệnh delMax từ hàng đợi ưu
tiên.

Câu 6.
Cho dãy số A = {25, 67, 34, 15, 42, 7, 9}. Hãy minh họa các bước thực hiện khi sắp xếp dãy …

06 25, 67, 34, 15, 42, 7, 9


06 25, 9, 34, 15, 42, 7, 67
06 25, 9, 7, 15, 42, 34, 67
063 15, 9, 7, 25, 42, 34, 67
02 15, 9, 7, 25, 42, 34, 67
022 7, 9, 15, 25, 42, 34, 67
46 7, 9, 15, 25, 42, 34, 67
465 7, 9, 15, 25, 34, 42, 67

Câu 7.
Cho một bảng băm kích thước 11 và một hàm băm (hash function) h(x) = x mod 11. Bạn cần thêm
vào bảng băm chuỗi khóa sau theo đúng thứ tự đã cho: 12, 56, 4, 77, 123, 83, 44, 23, 20, 38, 59.
a. Theo bạn phương pháp xử lý xung đột (collision) nào là phù hợp cho bài toán này? Hãy giải thích
lý do.
Separate chaining. Table too small for linear probing
If linear probing is selected, have to mention resizing array

6
b. Hãy trình bày quá trình chèn chuỗi khóa đã cho vào bảng băm bằng phương pháp mà bạn đã
chọn ở câu trên.
12, 56, 4, 77, 122, 83, 44, 23, 20, 38, 55
1 1 4 0 1 6 0 1 9 5 0

0 1 2 3 4 5 6 7 8 9 10

77 12 4 38 83 20
44 56
55 122
23

77 12 56 122 4 44 83 23 38 20 55

Câu 8.
d. Hãy vẽ cây nhị phân tìm kiếm (loại thường) mà bạn thu được sau khi thêm chuỗi khóa C B
A F G H D E (theo đúng thứ tự đó) vào một cây nhị phân tìm kiếm rỗng.
e. Hãy vẽ cây thu được sau khi xóa khóa 3 khỏi cây thu được từ phần a.
f. Hãy làm lại phần a nhưng sử dụng một cây tìm kiếm cân bằng. Hãy vẽ tình trạng cây sau khi
thêm từng khóa vào cây.

Câu 9.
Cho một đồ thị có hướng gồm 12 đỉnh và 18 cạnh liệt kê dưới đây
10⇾6, 4⇾5, 3⇾1, 2⇾8, 5⇾8, 0⇾5, 9⇾1, 9⇾10, 0⇾9,
1⇾10, 4⇾2, 8⇾4, 7⇾4, 7⇾0, 5⇾0, 10⇾3, 6⇾3, 3⇾11
c. Hãy vẽ biểu diễn danh sách kề của đồ thị. Các đình trong mỗi danh sách kề cần sắp xếp sẵn
theo thứ tự tăng dần. Thứ tự này sẽ được dùng cho phần b.

0 5, 9
1 10
2 8
3 1, 11
4 2, 5
5 0, 8
6 3
7 0, 4
8 4
9 1, 10
10 3, 6
11

7
d. Hãy dùng thuật toán tìm kiếm theo chiều sâu (depth-first search) để thăm từng đỉnh của đồ
thị, xuất phát từ đỉnh 0, Hãy viết trình tự các đỉnh theo thứ tự được thăm theo thuật toán.

0 5 8 4 2 >5 >0 9 1 10 3 11 >3 >10 6


05842 9 1 10 3 11 6

Vô hướng
0⇾9, 0⇾5, 1⇾10, 2⇾8, 3⇾1, 4⇾5, 5⇾8, 9⇾1, 9⇾10,
4⇾2, 8⇾4, 7⇾4, 7⇾0, 5⇾0, 10⇾3, 6⇾3, 3⇾11, 10⇾6

0 5, 7, 9
1 3, 9, 10
2 4, 8
3 1, 6, 10, 11
4 2, 5, 7, 8
5 0, 4, 8
6 3, 10
7 0, 4
8 2, 4, 5
9 0, 1, 10
10 1, 3, 6, 9
11 3.

05428 7 9 1 3 6 10 11
0 5 4 2 8 >2 >4 7 >4 >5 >0 9 1 3 6 10 >6 >3 11

Câu 10.
Cho một đồ thị vô hướng gồm 8 đỉnh và 16 cạnh có trọng số được liệt kê dưới đây
0-1 0.28 5 1-3 0.16 1 2-3 0.58 3-5 0.26 4 4-5 0.36 10x
0-4 0.32 7x 1-4 0.19 3 2-5 0.40 13 3-6 0.38 12x 4-7 0.29 6 x
0-6 0.35 9 1-5 0.34 8x 2-6 0.93 5-7 0.17 2
1-6 0.37 11x 2-7 0.52

Hãy sử dụng thuật toán Kruskal để tính cây bao trùm nhỏ nhất. Hãy liệt kê các cạnh trong cây bao
trùm nhỏ nhất lần lượt theo thứ tự tìm được.
1-3 5-7 1-4 3-5 0-1 0-6 2-5

Câu 11.
Cho một đồ thị có hướng gồm 8 đỉnh và 16 cạnh có trọng số cho dưới đây,

8
0⇾2 2.4 1⇾0 1.0 2⇾5 0.6 3⇾6 2.6 4⇾7 1.0
0⇾5 3.0 1⇾4 1.8 2⇾6 2.2 4⇾3 0.8 5⇾6 1.8
0⇾7 0.8 1⇾7 1.6 3⇾2 0.2 4⇾6 4.0 7⇾3 1.2
7⇾2 1.4
Hãy trình bày quá trình sử dụng thuật toán Dijkstra để tìm cây đường đi ngắn nhất xuất phát từ 1 tới
các đỉnh còn lại.

distTo
0 1 2 3 4 5 6 7

init ∞ 0 ∞ ∞ ∞ ∞ ∞ ∞

1 1.0 ∞ ∞ 1.8 ∞ ∞ 1.6

0 3.4 ∞ 1.8 4.0 ∞ 1.6

7 3.0 2.8 1.8 4.0 ∞

4 3.0 2.6 4.0 5.8

3 2.8 4.0 5.2

2 3.4 5.0

5 5.0

1-0, 1-7, 7-4, 7-3, 3-2, 2-5, 2-6,

Câu 12.
Hãy nêu thuật toán để giải bài sau đây:
Input: một dãy số độ dài tối đa 1 triệu a0, a1, … aN.
Output: một dãy số b0, b1…bN. Trong đó bi là số đứng gần nhất bên phải ai trong dãy input mà có giá
trị nhỏ hơn ai. Hoặc là giá trị -1 nếu bên phải ai không có giá trị nào nhỏ hơn ai
Ví dụ:
Input: 7461963
Output: 4 1 1 -1 6 3 -1

s = new Stack
for (i: N -> 0):
while !s.empty() && (s.top() >= a[i]): s.pop()
output( s.empty() ? -1 : s.pop())
s.push(a[i])

9
Câu 13.
Một mạng lưới tình báo được tổ chức như sau: Mỗi điệp viên chỉ biết 01 cấp trên trực tiếp của mình
và là cấp trên của tối đa 02 điệp viên khác. Người đứng đầu mạng lưới tất nhiên không có cấp trên.
Mỗi lần cần lan truyền một mẩu tin thì một người sẽ truyền tin cho cấp trên trực tiếp và các thuộc
cấp của mình nếu có, và họ sẽ tiếp tục truyền tin theo cách đó. Giả sử thời gian cần thiết cho một
người nhận tin và truyền cho cấp trên và các thuộc cấp là 01 phút và tất cả đều luôn luôn sẵn sàng
nhận và truyền tin suốt 24 tiếng mỗi ngày.
Bài toán đặt ra là khi cần lan truyền một mẩu tin từ một điệp viên tới toàn bộ lưới thì sau tối đa bao
nhiêu phút toàn bộ các điệp viên đều nhận được mẩu tin đó.

Hãy thiết kế cấu trúc dữ liệu Spy, mỗi đối tượng Spy biễu diễn thông tin về một điệp viên (cấp trên
và thuộc cấp của điệp viên đó)
Trình bày thuật toán cho một hàm có đầu vào là đối tượng Spy đứng đầu mạng lưới và trả về số
phút tối đa cần đến để truyền tin từ điệp viên bất kì đến toàn bộ lưới.

Cost (x) = Max (đường đi xuống từ x, dường từ x về gốc rồi từ gốc xuống
đáy)
= dường từ x về gốc rồi từ gốc xuống đáy -> 2 lần độ cao của cây

class Spy {
Spy boss, firstStaff, secondStaff;
int height = -1;
}

long maxDelay(Spy head) {


if head == null return 0
diameter = firstStaff.height() + secondStaff.height()
return max (diameter, maxDelay(firstStaff), maxDelay(secondStaff))
}

Int height(Spy spy) {


If spy == null return 0;
If spy.height < 0
spy.height = max(height(spy.firstStaff), height(spy.secondStaff))
return spy.height
}

Độ phức tạp: linear

Câu 14.

10
Cho dãy các số nguyên A gồm các phần tử a0, a1, …, aN, (0 < N <2000). Một dãy con không giảm là
dãy: ai1, ai2, …, aik trong đó (0<= i1 < i2 <…< ik <=N) và ai1 <= ai2 <= …<=aik. Trong các dãy con
không giảm như vậy sẽ có dãy con có tổng các phần tử là lớn nhất.

Trình bày ý tưởng và các bước chính thuật toán tìm được giá trị tổng lớn nhất của các dãy con
không giảm nêu trên.

Ví dụ:
Input: 1 101 2 3 100 4 5
Output: 106
(Vì 106 = 1 + 2 + 3 + 100)

Ý tưởng dùng phương pháp quy hoạch động


Giả mã:
for ( i = 0; i < n; i++ )
msis[i] = arr[i];

for ( i = 1; i < n; i++ )


for ( j = 0; j < i; j++ )
if (arr[i] > arr[j] &&
msis[i] < msis[j] + arr[i])
msis[i] = msis[j] + arr[i];

for ( i = 0; i < n; i++ )


if ( max < msis[i] )
max = msis[i];

return max;
Hết

11

You might also like