Bộ 5 đề ôn tập giữa kỳ Cấu trúc dữ liệu và Giải thuật (DSA)

Tin họcHChia sẻ bởi Hải Anh Nguyễn 0 lượt sử dụng đề

KHOA CÔNG NGHỆ THÔNG TIN

BỘ MÔN KHOA HỌC MÁY TÍNH

Đề ôn tập số 01

ĐỀ ÔN TẬP GIỮA KỲ HỌC PHẦN DSA

Môn: Cấu trúc dữ liệu và Giải thuật

Thời gian làm bài: 60 phút (không kể thời gian phát đề)

PHẦN I. TRẮC NGHIỆM (3,0 điểm)

Thí sinh chọn một phương án đúng duy nhất cho mỗi câu hỏi sau:

Câu 1. Trong thuật toán Quick-Find, độ phức tạp thời gian trong trường hợp tồi nhất của thao tác `union(p, q)` trên tập NN phần tử là:

A. Θ(1)\Theta(1)

B. Θ(log⁡N)\Theta(\log N)

C. Θ(N)\Theta(N)

D. Θ(N2)\Theta(N^2)

Câu 2. Cho một Stack rỗng. Thực hiện chuỗi thao tác: `push(3)`, `push(5)`, `pop()`, `push(7)`, `push(9)`, `pop()`. Giá trị còn lại ở đỉnh Stack là:

A. 33

B. 55

C. 77

D. 99

Câu 3. Thuật toán Sắp xếp Chèn (Insertion Sort) thực hiện số phép so sánh ít nhất ∼N\sim N khi dãy đầu vào có đặc điểm gì?

A. Đã được sắp xếp giảm dần

B. Đã được sắp xếp tăng dần (hoặc gần như đã sắp xếp)

C. Các phần tử ngẫu nhiên

D. Nửa đầu tăng dần, nửa sau giảm dần

Câu 4. Đâu là phát biểu ĐÚNG về thuật toán Mergesort?

A. Thuật toán sắp xếp tại chỗ (In-place) không tốn bộ nhớ phụ

B. Độ phức tạp thời gian trường hợp tồi nhất là O(N2)O(N^2)

C. Thuật toán có tính chất ổn định (Stable) và cần bộ nhớ phụ O(N)O(N)

D. Chạy nhanh nhất khi mảng đầu vào đã sắp xếp ngược

Câu 5. Cho Max Heap nhị phân biểu diễn dưới dạng mảng (chỉ số bắt đầu từ 11). Nút ở chỉ số kk (k>1k > 1) có nút cha nằm ở chỉ số nào?

A. 2k2k

B. 2k+12k + 1

C. ⌊k/2⌋\lfloor k/2 \rfloor

D. k−1k - 1

Câu 6. Để thu được danh sách các khóa theo thứ tự tăng dần từ một Cây tìm kiếm nhị phân (BST), ta thực hiện duyệt cây theo thứ tự nào?

A. Preorder (Tiền tự)

B. Inorder (Trung tự)

C. Postorder (Hậu tự)

D. Level-order (Theo tầng)

Câu 7. Cấu trúc dữ liệu Weighted Quick-Union đảm bảo chiều cao tối đa của bất kỳ cây nào chứa NN phần tử không vượt quá:

A. log⁡2N\log_2 N

B. N/2N/2

C. N\sqrt{N}

D. N−1N - 1

Câu 8. Thuật toán Quickselect dùng để tìm phần tử nhỏ thứ kk trong mảng NN phần tử có độ phức tạp thời gian trung bình (khi đã shuffle) là:

A. O(log⁡N)O(\log N)

B. O(N)O(N)

C. O(Nlog⁡N)O(N \log N)

D. O(N2)O(N^2)

Câu 9. Thuật toán sắp xếp nào dưới đây KHÔNG phải là thuật toán sắp xếp tại chỗ (In-place)?

A. Selection Sort

B. Insertion Sort

C. Mergesort

D. Heapsort

Câu 10. Khi thêm một phần tử mới vào Max Heap nhị phân chứa NN phần tử, số phép so sánh nhiều nhất cần thực hiện (thao tác `swim`) là:

A. 11

B. ∼log⁡2N\sim \log_2 N

C. ∼N/2\sim N/2

D. ∼N\sim N

Câu 11. Biểu thức Tilde (∼\sim) xấp xỉ cho hàm f(N)=2N3−15N2+100Nf(N) = 2N^3 - 15N^2 + 100N khi NN rất lớn là:

A. ∼2N3\sim 2N^3

B. ∼−15N2\sim -15N^2

C. ∼N3\sim N^3

D. ∼2N3−15N2\sim 2N^3 - 15N^2

Câu 12. Cho Danh sách liên kết đơn có hai con trỏ `head` và `tail`. Thao tác nào sau đây có độ phức tạp thời gian tồi nhất là O(N)O(N)?

A. Thêm phần tử vào đầu danh sách (`addFirst`)

B. Thêm phần tử vào cuối danh sách (`addLast`)

C. Xóa phần tử ở đầu danh sách (`removeFirst`)

D. Xóa phần tử ở cuối danh sách (`removeLast`)

Câu 13. Thuật toán Sắp xếp Chọn (Selection Sort) có đặc điểm nào sau đây?

A. Số phép đổi chỗ (exchange) luôn là O(N)O(N) trong mọi trường hợp

B. Là thuật toán sắp xếp ổn định (Stable)

C. Số phép so sánh phụ thuộc nhiều vào dữ liệu đầu vào

D. Bộ nhớ phụ cần dùng là O(N)O(N)

Câu 14. Trong thuật toán Dijkstra 2-stack để tính giá trị biểu thức số học, khi gặp toán tử (ví dụ `+`, `*`), ta xử lý như thế nào?

A. Pop hai giá trị ra tính toán ngay

B. Đẩy toán tử vào stack toán tử (`ops`)

C. Bỏ qua toán tử

D. Đẩy toán tử vào stack giá trị (`vals`)

Câu 15. Chiều cao tồi nhất (worst-case height) của một cây BST chứa NN phần tử là:

A. log⁡2N\log_2 N

B. N\sqrt{N}

C. N−1N - 1

D. N/2N/2

PHẦN II. TỰ LUẬN (7,0 điểm)

Câu 1 (1,5 điểm - Phân tích độ phức tạp).
Cho đoạn mã nguồn C++ / Java sau:

int countPairs(int a[], int N) {
int count = 0;
for (int i = 0; i < N; i++) {
for (int j = i + 1; j < N; j++) {
if (a[i] == a[j]) {
count++;
}
}
}
return count;
}

a) Hãy tính chính xác số lần thực hiện phép so sánh `a[i] == a[j]` theo NN.
b) Cho biết độ phức tạp tính toán theo ký hiệu OO và ký hiệu Tilde (∼\sim) của thuật toán trên.

Câu 2 (1,5 điểm - Stack & Queue).
a) Cho một Queue QQ rỗng. Cho chuỗi thao tác:

enqueue(10)→enqueue(20)→dequeue()→enqueue(30)→enqueue(40)→dequeue()→isEmpty()\text{enqueue}(10) \to \text{enqueue}(20) \to \text{dequeue}() \to \text{enqueue}(30) \to \text{enqueue}(40) \to \text{dequeue}() \to \text{isEmpty}()

Hãy cho biết trạng thái của Queue QQ sau mỗi thao tác và giá trị trả về của các thao tác `dequeue()`, `isEmpty()` (Quy ước bên phải là đầu ra / đầu lấy phần tử của Queue).
b) Viết hàm bằng mã giả hoặc Java `void reverseK(Queue<Integer> q, int k)` sử dụng đúng 0101 Stack phụ để đảo ngược thứ tự kk phần tử đầu tiên của Queue qq, giữ nguyên thứ tự tương đối của các phần tử còn lại.

Câu 3 (1,5 điểm - Sắp xếp & Heap).
a) Cho dãy số A=[18,12,25,6,30,15]A = [18, 12, 25, 6, 30, 15]. Minh họa từng bước quá trình sắp xếp dãy AA tăng dần bằng thuật toán Insertion Sort.
b) Cho mảng Max Heap nhị phân hiện tại: `[-, T, S, R, A, C, B]` (ô đầu tiên để trống ở chỉ số 0). Minh họa từng bước quá trình thêm khóa `U` vào heap.

Câu 4 (1,5 điểm - Cây tìm kiếm nhị phân BST).
a) Vẽ cây nhị phân tìm kiếm thu được sau khi thêm lần lượt chuỗi khóa `E, C, G, A, D, F, H` vào cây rỗng.
b) Viết hàm đệ quy tính chiều cao (`height`) của cây BST.

Câu 5 (1,0 điểm - Bài toán ứng dụng).
Hãy thiết kế cấu trúc dữ liệu `MinMaxStack` hỗ trợ các thao tác `push(x)`, `pop()`, `getMin()`, `getMax()` đều đạt độ phức tạp thời gian O(1)O(1) trong trường hợp tồi nhất và bộ nhớ phụ O(N)O(N). Mô tả ý tưởng và mã giả.

--------- HẾT ĐỀ SỐ 1 ---------

KHOA CÔNG NGHỆ THÔNG TIN

BỘ MÔN KHOA HỌC MÁY TÍNH

Đề ôn tập số 02

ĐỀ ÔN TẬP GIỮA KỲ HỌC PHẦN DSA

Môn: Cấu trúc dữ liệu và Giải thuật

Thời gian làm bài: 60 phút (không kể thời gian phát đề)

PHẦN I. TRẮC NGHIỆM (3,0 điểm)

Thí sinh chọn một phương án đúng duy nhất cho mỗi câu hỏi sau:

Câu 1. Thao tác `connected(p, q)` trong thuật toán Quick-Union cơ bản có độ phức tạp tồi nhất là:

A. O(1)O(1)

B. O(log⁡N)O(\log N)

C. O(N)O(N)

D. O(N2)O(N^2)

Câu 2. Hàng đợi (Queue) là cấu trúc dữ liệu hoạt động theo nguyên tắc nào?

A. LIFO (Last In First Out)

B. FIFO (First In First Out)

C. Random Access

D. Highest Priority First

Câu 3. Thuật toán Sắp xếp Nổi bọt (Bubble Sort) cải tiến (dừng khi không có phép đổi chỗ) có độ phức tạp tốt nhất (Best case) là:

A. O(1)O(1)

B. O(N)O(N)

C. O(Nlog⁡N)O(N \log N)

D. O(N2)O(N^2)

Câu 4. Trong thuật toán Mergesort Top-down, mảng phụ `aux` nên được cấp phát bộ nhớ ở đâu để tối ưu hiệu năng?

A. Bên trong hàm đệ quy `sort()`

B. Tạo một lần duy nhất ở hàm khởi tạo / hàm gọi ngoài cùng

C. Cấp phát động tại hàm `merge()`

D. Không cần dùng mảng phụ

Câu 5. Cho mảng biểu diễn Max Heap: `[-, 90, 70, 80, 30, 40, 50, 60]`. Khóa con trái và con phải của nút có giá trị 7070 lần lượt là:

A. 80,3080, 30

B. 30,4030, 40

C. 50,6050, 60

D. 90,8090, 80

Câu 6. Khi xóa một nút XX có đầy đủ 22 con trong cây BST, ta thay thế XX bằng nút nào để giữ nguyên tính chất BST?

A. Nút gốc của cây

B. Nút nhỏ nhất trên cây con bên trái hoặc nút lớn nhất trên cây con bên phải

C. Nút lớn nhất trên cây con bên trái (Predecessor) hoặc nút nhỏ nhất trên cây con bên phải (Successor)

D. Nút lá bất kỳ

Câu 7. Thuật toán 3-way Quicksort (phân chia 3 đoạn) đạt hiệu năng vượt trội O(N)O(N) khi mảng đầu vào có đặc điểm gì?

A. Đã được sắp xếp hoàn toàn

B. Chứa rất nhiều khóa trùng lặp (nhiều phần tử bằng nhau)

C. Mảng có kích thước rất nhỏ

D. Mảng giảm dần

Câu 8. Đối với Danh sách liên kết kép (Doubly Linked List) có con trỏ `head` và `tail`, thao tác xóa phần tử ở cuối danh sách (`removeLast`) có độ phức tạp thời gian là:

A. O(1)O(1)

B. O(log⁡N)O(\log N)

C. O(N)O(N)

D. O(N2)O(N^2)

Câu 9. Thuật toán sắp xếp nào dưới đây KHÔNG có tính ổn định (Unstable)?

A. Insertion Sort

B. Mergesort

C. Quicksort

D. Selection Sort (khi cài trên DSLK)

Câu 10. Phép toán `sink(k)` (hạ xuống) trong Max Heap được sử dụng trong thao tác nào?

A. Thêm phần tử mới (`insert`)

B. Xóa phần tử lớn nhất (`delMax`) và dựng Heap

C. Lấy giá trị lớn nhất (`getMax`)

D. Kiểm tra heap rỗng

Câu 11. Số phép so sánh nhiều nhất trong trường hợp tồi nhất của thuật toán Tìm kiếm nhị phân (Binary Search) trên mảng NN phần tử là:

A. ∼log⁡2N\sim \log_2 N

B. ∼N\sim N

C. ∼N/2\sim N/2

D. ∼Nlog⁡2N\sim N \log_2 N

Câu 12. Trong cài đặt Stack bằng mảng tự điều chỉnh kích thước (Resizing Array), mảng sẽ gấp đôi dung lượng khi nào?

A. Stack bị rỗng

B. Số phần tử NN bằng kích thước mảng CC (N==CN == C)

C. Số phần tử NN bằng C/2C/2

D. Số phần tử NN bằng C/4C/4

Câu 13. Biểu thức Trung tố (A+B)∗C(A + B) * C khi chuyển sang biểu thức Hậu tố (Postfix) là:

A. A B + C ∗A\ B\ +\ C\ *

B. A B C + ∗A\ B\ C\ +\ *

C. ∗ + A B C*\ +\ A\ B\ C

D. A B ∗ C +A\ B\ *\ C\ +

Câu 14. Nếu thêm lần lượt các khóa đã sắp xếp tăng dần 10,20,30,40,5010, 20, 30, 40, 50 vào một cây BST rỗng, cây thu được sẽ có dạng gì?

A. Cây cân bằng hoàn hảo

B. Cây bị suy biến thành danh sách tuyến tính lệch phải

C. Cây nhị phân đầy đủ

D. Heap max

Câu 15. Kỹ thuật "Shuffle" (tráo ngẫu nhiên mảng) trước khi chạy Quicksort nhằm mục đích gì?

A. Tăng tính ổn định của thuật toán

B. Đảm bảo thời gian chạy O(Nlog⁡N)O(N \log N) với xác suất cực cao, tránh trường hợp tồi nhất O(N2)O(N^2)

C. Giảm bộ nhớ phụ

D. Chuyển mảng thành Max Heap

PHẦN II. TỰ LUẬN (7,0 điểm)

Câu 1 (1,5 điểm - Phân tích thuật toán).
Cho đoạn code Java sau tính tổng các phần tử mảng:

void processArray(int a[], int N) {
int sum = 0;
for (int i = 1; i < N; i *= 2) {
for (int j = 0; j < i; j++) {
sum += a[j];
}
}
}

a) Tính số lần thực hiện lệnh `sum += a[j]` theo NN khi N=2kN = 2^k.
b) Xác định cấp phát triển (Order of growth) theo OO của đoạn code trên.

Câu 2 (1,5 điểm - Stack & Queue).
a) Cho một Stack SS rỗng. Cho chuỗi thao tác:

push(7)→push(6)→push(5)→pop()→isEmpty()→push(8)→pop()\text{push}(7) \to \text{push}(6) \to \text{push}(5) \to \text{pop}() \to \text{isEmpty}() \to \text{push}(8) \to \text{pop}()

Cho biết tình trạng Stack sau mỗi thao tác và kết quả trả về của các hàm `pop()`, `isEmpty()`.
b) Viết hàm `boolean isBalanced(String expr)` sử dụng Stack để kiểm tra tính hợp lệ của các cặp dấu ngoặc `()`, `[]`, `{}` trong chuỗi `expr`.

Câu 3 (1,5 điểm - Sắp xếp & Heap).
a) Cho mảng chưa sắp xếp A=[4,1,3,2,16,9,10,14,8,7]A = [4, 1, 3, 2, 16, 9, 10, 14, 8, 7]. Hãy minh họa quá trình dựng Max Heap tại chỗ (`buildHeap` bằng phương pháp bottom-up / dùng `sink`).
b) Cho mảng Max Heap hiện tại: `[-, U, T, S, B, D, C]`. Minh họa từng bước xóa phần tử lớn nhất khỏi heap.

Câu 4 (1,5 điểm - Cây BST).
a) Cho chuỗi khóa `M, B, D, C, A, S, H, P, E`. Vẽ cây BST thu được sau khi thêm chuỗi khóa trên vào cây rỗng.
b) Viết hàm đệ quy `int countLeaves(Node root)` đếm số lượng nút lá (nút không có con) trong cây BST.

Câu 5 (1,0 điểm - Bài toán ứng dụng).
Cho một mảng AA chứa NN số nguyên, trong đó có một phần tử xuất hiện nhiều hơn N/2N/2 lần (phần tử đa số - Majority Element). Hãy đề xuất thuật toán tìm phần tử này với thời gian O(N)O(N) hoặc O(Nlog⁡N)O(N \log N) và bộ nhớ phụ O(1)O(1) (gợi ý: dùng Quickselect hoặc Boyer-Moore Voting).

--------- HẾT ĐỀ SỐ 2 ---------

KHOA CÔNG NGHỆ THÔNG TIN

BỘ MÔN KHOA HỌC MÁY TÍNH

Đề ôn tập số 03

ĐỀ ÔN TẬP GIỮA KỲ HỌC PHẦN DSA

Môn: Cấu trúc dữ liệu và Giải thuật

Thời gian làm bài: 60 phút (không kể thời gian phát đề)

PHẦN I. TRẮC NGHIỆM (3,0 điểm)

Thí sinh chọn một phương án đúng duy nhất cho mỗi câu hỏi sau:

Câu 1. Trong thuật toán Weighted Quick-Union với Path Compression, độ phức tạp thời gian amortized cho mỗi thao tác find/union là:

A. O(1)O(1)

B. O(α(N))O(\alpha(N)) (Gần như hằng số, α\alpha là hàm Inverse Ackermann)

C. O(log⁡N)O(\log N)

D. O(N)O(N)

Câu 2. Cấu trúc dữ liệu nào phù hợp nhất để quản lý chức năng "Undo" (Hoàn tác) trong trình soạn thảo văn bản?

A. Queue

B. Stack

C. Priority Queue

D. Binary Search Tree

Câu 3. Thuật toán Selection Sort thực hiện bao nhiêu phép đổi chỗ (swap/exchange) trong trường hợp tồi nhất đối với mảng NN phần tử?

A. ∼N2/2\sim N^2/2

B. ∼Nlog⁡N\sim N \log N

C. N−1N - 1 (Tuyến tính O(N)O(N))

D. 00

Câu 4. Nhược điểm lớn nhất của Mergesort so với Quicksort là gì?

A. Độ phức tạp trường hợp tồi nhất lớn hơn

B. Cần O(N)O(N) bộ nhớ phụ cho mảng trộn

C. Không có tính ổn định

D. Chạy chậm trên dữ liệu lớn

Câu 5. Chiều cao của một Cây nhị phân hoàn chỉnh (Complete Binary Tree) chứa NN nút là:

A. ⌊log⁡2N⌋\lfloor \log_2 N \rfloor

B. N/2N/2

C. N−1N - 1

D. N\sqrt{N}

Câu 6. Trong cây BST, thao tác `select(k)` trả về thông tin gì?

A. Khóa có giá trị bằng kk

B. Khóa có xếp hạng (rank) đúng bằng kk (khóa nhỏ thứ kk)

C. Độ sâu của nút kk

D. Chiều cao của cây con tại kk

Câu 7. Trong thuật toán Quicksort tiêu chuẩn (hoặc Lomuto/Hoare partition), sau bước phân chia (partitioning) đầu tiên với chốt vv, vị trí của chốt vv có đặc điểm gì?

A. Nằm ở đầu mảng

B. Nằm ở cuối mảng

C. Đã đứng đúng vị trí chính xác của nó trong mảng sau khi sắp xếp

D. Luôn nằm chính giữa mảng

Câu 8. Thuật toán Heapsort có độ phức tạp thời gian trong trường hợp tồi nhất là:

A. O(N2)O(N^2)

B. O(Nlog⁡N)O(N \log N)

C. O(N)O(N)

D. O(log⁡N)O(\log N)

Câu 9. Cho mảng Max Heap: `[-, 95, 80, 75, 30, 40, 50, 60]`. Sau khi thực hiện 1 thao tác `delMax()`, giá trị ở gốc Heap mới là bao nhiêu?

A. 9595

B. 8080

C. 7575

D. 6060

Câu 10. Trong Danh sách liên kết đơn, để chèn một nút mới vào ngay sau nút PP, ta cần thực hiện các lệnh nào (theo thứ tự)?

A. `P.next = newNode; newNode.next = P.next;`

B. `newNode.next = P.next; P.next = newNode;`

C. `P.next = newNode; newNode.next = null;`

D. `newNode.next = P; P = newNode;`

Câu 11. Vòng lặp `for (int i = N; i > 0; i /= 2)` thực hiện bao nhiêu lần lặp?

A. NN

B. N/2N/2

C. ⌊log⁡2N⌋+1\lfloor \log_2 N \rfloor + 1

D. N2N^2

Câu 12. Cho biểu thức Hậu tố (Postfix): `5 3 2 * + 4 -`. Giá trị của biểu thức là:

A. 77

B. 1111

C. 1212

D. 1515

Câu 13. Trong mảng vòng (Circular Array) dùng cài đặt Queue kích thước MM, vị trí tiếp theo của chỉ số `rear` sau khi tăng được tính theo công thức nào?

A. `(rear + 1) % M`

B. `rear + 1`

C. `(rear % M) + 1`

D. `rear % (M + 1)`

Câu 14. Thao tác `floor(key)` trong cây BST trả về:

A. Khóa nhỏ nhất trong cây

B. Khóa lớn nhất trong cây nhỏ hơn hoặc bằng `key`

C. Khóa nhỏ nhất trong cây lớn hơn hoặc bằng `key`

D. Chiều sâu của `key`

Câu 15. Thuật toán sắp xếp nào sau đây hoạt động theo mô hình Chia để trị (Divide and Conquer)?

A. Selection Sort

B. Insertion Sort

C. Mergesort

D. Heapsort

PHẦN II. TỰ LUẬN (7,0 điểm)

Câu 1 (1,5 điểm - Phân tích thuật toán).
Cho đoạn code sau kiểm tra mảng:

void checkMatch(int a[], int N) {
int count = 0;
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
if (i < j && a[i] == a[j]) {
count++;
}
}
}
}

a) Tính chính xác số lần phép so sánh `a[i] == a[j]` được thực hiện.
b) Tính số lần phép so sánh `i < j` được thực hiện. Độ phức tạp OO của thuật toán là gì?

Câu 2 (1,5 điểm - Stack & Queue / Danh sách liên kết).
a) Cho Queue QQ rỗng. Thực hiện:

enqueue(3)→dequeue()→isEmpty()→enqueue(2)→enqueue(1)→dequeue()\text{enqueue}(3) \to \text{dequeue}() \to \text{isEmpty}() \to \text{enqueue}(2) \to \text{enqueue}(1) \to \text{dequeue}()

Trình bày trạng thái Queue sau mỗi bước và kết quả các hàm.
b) Viết hàm bằng Java/mã giả `Node removeAllX(Node head, int x)` xóa tất cả các nút có giá trị bằng xx khỏi Danh sách liên kết đơn.

Câu 3 (1,5 điểm - Sắp xếp & Heap).
a) Cho mảng A=[45,12,89,34,67,23,10]A = [45, 12, 89, 34, 67, 23, 10]. Minh họa từng bước quá trình sắp xếp mảng AA tăng dần bằng Mergesort Top-down (vẽ cây đệ quy trộn).
b) Cho mảng Max Heap nhị phân: `[-, 90, 80, 70, 20, 40, 30]`. Minh họa từng bước quá trình thêm khóa 8585 vào Heap.

Câu 4 (1,5 điểm - Cây BST).
a) Thêm các khóa 50,30,70,20,40,60,8050, 30, 70, 20, 40, 60, 80 vào cây BST rỗng. Vẽ cây kết quả. Sau đó vẽ cây thu được sau khi xóa khóa 3030.
b) Viết hàm đệ quy `Key maxKey(Node root)` trả về giá trị khóa lớn nhất trong cây BST.

Câu 5 (1,0 điểm - Bài toán ứng dụng).
Thiết kế thuật toán độ phức tạp O(log⁡N)O(\log N) tìm chỉ số ii của phần tử 11 đầu tiên trong mảng đã sắp xếp chỉ chứa các số 00 và 11 (giả sử mảng có dạng [0,0,…,0,1,1,…,1][0, 0, \dots, 0, 1, 1, \dots, 1]). Viết mã giả dựa trên Tìm kiếm nhị phân.

--------- HẾT ĐỀ SỐ 3 ---------

KHOA CÔNG NGHỆ THÔNG TIN

BỘ MÔN KHOA HỌC MÁY TÍNH

Đề ôn tập số 04

ĐỀ ÔN TẬP GIỮA KỲ HỌC PHẦN DSA

Môn: Cấu trúc dữ liệu và Giải thuật

Thời gian làm bài: 60 phút (không kể thời gian phát đề)

PHẦN I. TRẮC NGHIỆM (3,0 điểm)

Thí sinh chọn một phương án đúng duy nhất cho mỗi câu hỏi sau:

Câu 1. Trong bài toán Dynamic Connectivity, tập hợp các phần tử liên thông tạo thành một:

A. Quan hệ thứ tự toàn phần

B. Quan hệ tương đương (Equivalence relation)

C. Cây nhị phân

D. Đồ thị có hướng không chu trình (DAG)

Câu 2. Chuyển biểu thức Trung tố A∗(B+C)/DA * (B + C) / D sang biểu thức Hậu tố (Postfix):

A. A B C + ∗ D /A\ B\ C\ +\ *\ D\ /

B. A B + C ∗ D /A\ B\ +\ C\ *\ D\ /

C. A B C ∗ + D /A\ B\ C\ *\ +\ D\ /

D. ∗ A + B C / D*\ A\ +\ B\ C\ /\ D

Câu 3. Thuật toán sắp xếp nào có số phép truy nhập mảng (Array accesses) ít nhất trong trường hợp tồi nhất đối với mảng đã sắp xếp ngược?

A. Insertion Sort

B. Selection Sort

C. Quicksort

D. Bubble Sort

Câu 4. Trong thuật toán 3-way Quicksort, sau khi phân chia mảng theo chốt vv, mảng được chia thành 3 đoạn nào?

A. <v< v, =v= v, >v> v

B. ≤v\le v, =v= v, ≥v\ge v

C. <v< v, >v> v, =v= v

D. Trái, Giữa, Phải

Câu 5. Trong một Min Heap nhị phân, phần tử nhỏ nhất luôn nằm ở vị trí nào?

A. Nút lá cuối cùng

B. Nút gốc (chỉ số 1)

C. Nút con trái của gốc

D. Nút bất kỳ ở tầng cuối

Câu 6. Nút gốc (Root) của một cây nhị phân có đặc điểm gì?

A. Không có con

B. Không có nút cha (Parent is null)

C. Luôn có 2 con

D. Có độ sâu bằng chiều cao cây

Câu 7. Nếu chạy Quicksort tiêu chuẩn (chọn chốt là phần tử đầu tiên, không shuffle) trên mảng đã sắp xếp tăng dần, độ phức tạp thời gian sẽ là:

A. O(N)O(N)

B. O(Nlog⁡N)O(N \log N)

C. O(N2)O(N^2)

D. O(log⁡N)O(\log N)

Câu 8. Kỹ thuật "Bồi hoàn" (Amortized Analysis) cho thao tác `push` trên Stack dùng mảng tự gấp đôi kích thước cho kết quả độ phức tạp trung bình là:

A. O(1)O(1)

B. O(log⁡N)O(\log N)

C. O(N)O(N)

D. O(N2)O(N^2)

Câu 9. Thuật toán Sắp xếp Chèn (Insertion Sort) chạy mất thời gian O(N)O(N) khi mảng đầu vào có số cặp nghịch đảo (inversions) là:

A. O(N2)O(N^2)

B. O(Nlog⁡N)O(N \log N)

C. O(N)O(N) (Mảng gần như đã sắp xếp)

D. O(N3)O(N^3)

Câu 10. Trong Max Heap nhị phân (mảng từ index 1), thao tác `swim(k)` thực hiện so sánh khóa ở vị trí kk với nút nào?

A. k+1k + 1

B. 2k2k

C. ⌊k/2⌋\lfloor k/2 \rfloor

D. k−1k - 1

Câu 11. Số lượng liên kết null trong một cây nhị phân có NN nút là bao nhiêu?

A. NN

B. N−1N - 1

C. N+1N + 1

D. 2N2N

Câu 12. Mảng gồm NN phần tử có số lượng cặp nghịch đảo (inversions) nhiều nhất là bao nhiêu?

A. NN

B. N(N−1)2\dfrac{N(N - 1)}{2}

C. Nlog⁡2NN \log_2 N

D. N2N^2

Câu 13. Trong cây BST, thao tác `ceiling(key)` trả về khóa nào?

A. Khóa nhỏ nhất trong cây lớn hơn hoặc bằng `key`

B. Khóa lớn nhất trong cây nhỏ hơn hoặc bằng `key`

C. Khóa ở tầng trên cùng

D. Khóa gốc

Câu 14. Cấu trúc dữ liệu Túi (Bag) khác Stack và Queue ở điểm cơ bản nào?

A. Không cho phép chứa các phần tử trùng lặp

B. Không hỗ trợ thao tác xóa phần tử chỉ định (chỉ hỗ trợ thêm và duyệt)

C. Có dung lượng cố định

D. Chỉ lưu trữ kiểu dữ liệu số nguyên

Câu 15. Độ phức tạp không gian (Auxiliary Space) của thuật toán Quicksort tiêu chuẩn (do bộ nhớ stack đệ quy) trong trường hợp trung bình là:

A. O(1)O(1)

B. O(log⁡N)O(\log N)

C. O(N)O(N)

D. O(Nlog⁡N)O(N \log N)

PHẦN II. TỰ LUẬN (7,0 điểm)

Câu 1 (1,5 điểm - Phân tích thuật toán).
Cho thuật toán Tìm kiếm nhị phân (Binary Search).
a) Tính số lần gọi hàm `compare` trong trường hợp tốt nhất và tồi nhất theo NN.
b) Giải thích ý nghĩa của công thức `mid = lo + (hi - lo) / 2` thay vì `(lo + hi) / 2`.

Câu 2 (1,5 điểm - Stack & Queue).
a) Cho Queue QQ rỗng. Cho chuỗi thao tác:

enqueue(7)→enqueue(6)→enqueue(5)→dequeue()→isEmpty()\text{enqueue}(7) \to \text{enqueue}(6) \to \text{enqueue}(5) \to \text{dequeue}() \to \text{isEmpty}()

Cho biết tình trạng Queue và giá trị trả về.
b) Viết hàm `String infixToPostfix(String exp)` chuyển biểu thức Trung tố có ngoặc sang Hậu tố bằng thuật toán Dijkstra 2-stack.

Câu 3 (1,5 điểm - Sắp xếp & Heap).
a) Cho Max Heap nhị phân hiện tại: `[-, 85, 75, 60, 40, 50, 30]`. Minh họa từng bước quá trình thêm khóa 6868 vào Heap.
b) Tiếp tục với Heap thu được ở câu a, minh họa từng bước xóa phần tử lớn nhất (`delMax`).

Câu 4 (1,5 điểm - Cây BST).
a) Cho chuỗi khóa 80,20,40,30,10,100,70,90,5080, 20, 40, 30, 10, 100, 70, 90, 50. Vẽ cây BST thu được sau khi thêm lần lượt chuỗi khóa trên vào cây rỗng.
b) Viết hàm đệ quy `int sumKeys(Node root)` tính tổng giá trị tất cả các khóa số nguyên trong cây BST.

Câu 5 (1,0 điểm - Bài toán ứng dụng).
Thiết kế cấu trúc dữ liệu `UniStack` chứa các chuỗi String hỗ trợ `push(x)` và `pop()` như Stack thông thường nhưng đảm bảo không chứa phần tử trùng lặp. Yêu cầu: `push` và `pop` tốn thời gian O(1)O(1) hoặc O(log⁡N)O(\log N), bộ nhớ O(N)O(N).

--------- HẾT ĐỀ SỐ 4 ---------

ĐÁP ÁN VÀ LỜI GIẢI CHI TIẾT ĐỀ SỐ 4

1. Đáp án trắc nghiệm Đề số 4

Câu

Đáp án

Giải thích tóm tắt

1

B

Tính liên thông có tính phản xạ, đối xứng và bắc cầu nên lập thành quan hệ tương đương.

2

A

Thứ tự ưu tiên ngoặc: (B+C)→B C +(B + C) \to B\ C\ +, nhân với A→A B C + ∗A \to A\ B\ C\ +\ *, chia cho D→A B C + ∗ D /D \to A\ B\ C\ +\ *\ D\ /.

3

B

Selection Sort luôn thực hiện đúng N−1N - 1 phép đổi chỗ trong mọi trường hợp, ít truy nhập mảng hơn Insertion/Bubble khi mảng ngược.

4

A

3-way partitioning chia mảng thành các đoạn <v< v, =v= v, >v> v để xử lý hiệu quả các khóa trùng lặp.

5

B

Tính chất Min Heap: Nút cha luôn nhỏ hơn hoặc bằng nút con, do đó gốc (chỉ số 1) luôn là phần tử nhỏ nhất.

6

B

Nút gốc là nút duy nhất không có con trỏ trỏ tới từ nút khác (Parent is null).

7

C

Khi mảng đã sắp xếp, chọn chốt ở đầu mảng khiến cây đệ quy bị suy biến thành độ sâu NN, thời gian O(N2)O(N^2).

8

A

Mảng tự gấp đôi kích thước có chi phí bồi hoàn (amortized cost) cho thao tác `push` là O(1)O(1).

9

C

Thời gian chạy của Insertion Sort xấp xỉ O(N+I)O(N + I) với II là số cặp nghịch đảo. Khi I=O(N)I = O(N), thời gian chạy là O(N)O(N).

10

C

Trong mảng đánh số từ 1, nút cha của nút kk nằm tại chỉ số ⌊k/2⌋\lfloor k/2 \rfloor.

11

C

Mỗi nút có 2 con trỏ, NN nút có 2N2N con trỏ. Đúng N−1N - 1 nút có cha (được trỏ tới), nên số con trỏ null là 2N−(N−1)=N+12N - (N - 1) = N + 1.

12

B

Mảng sắp xếp ngược hoàn toàn có số cặp nghịch đảo tối đa là N(N−1)2\dfrac{N(N - 1)}{2}.

13

A

`ceiling(key)` trả về khóa nhỏ nhất trong tập khóa lớn hơn hoặc bằng `key`.

14

B

Bag là tập hợp chỉ cho phép thêm (`add`) và duyệt (`iterator`), không hỗ trợ xóa phần tử chỉ định.

15

B

Cây đệ quy của Quicksort có độ sâu trung bình là O(log⁡N)O(\log N), tiêu tốn O(log⁡N)O(\log N) bộ nhớ Stack.

2. Lời giải tự luận Đề số 4

Câu 1 (1,5 điểm)
a) Số lần gọi `compare`:
- Trường hợp tốt nhất: 11 lần (khi `a[mid] == key` ngay lần thử đầu tiên tại điểm giữa).
- Trường hợp tồi nhất: ⌊log⁡2N⌋+1\lfloor \log_2 N \rfloor + 1 lần (khi không tìm thấy khóa hoặc khóa ở tận nhánh con chia đôi cuối cùng).

b) Ý nghĩa công thức `mid = lo + (hi - lo) / 2`:
- Về mặt đại số, lo+(hi−lo)/2=(lo+hi)/2lo + (hi - lo) / 2 = (lo + hi) / 2.
- Trong ngôn ngữ lập trình (Java/C++), nếu lolo và hihi lớn, tổng lo+hilo + hi có thể vượt quá giá trị cực đại của số nguyên 32-bit có dấu (231−1=2 147 483 6472^{31} - 1 = 2\,147\,483\,647), dẫn đến hiện tượng tràn số (integer overflow) làm kết quả bị âm.
- Biểu thức lo+(hi−lo)/2lo + (hi - lo) / 2 thực hiện phép trừ trước (hi−lo≥0hi - lo \ge 0) nên không bao giờ xảy ra tràn số.

Câu 2 (1,5 điểm)
a) Trạng thái Queue QQ qua từng thao tác (quy ước bên phải là đầu ra):
- enqueue(7)→Q:[7]\text{enqueue}(7) \to Q: [7]
- enqueue(6)→Q:[6,7]\text{enqueue}(6) \to Q: [6, 7]
- enqueue(5)→Q:[5,6,7]\text{enqueue}(5) \to Q: [5, 6, 7]
- dequeue()→\text{dequeue}() \to Trả về giá trị 77, trạng thái Q:[5,6]Q: [5, 6]
- isEmpty()→\text{isEmpty}() \to Trả về `false`, trạng thái Q:[5,6]Q: [5, 6]

b) Hàm `infixToPostfix` bằng Java:

public static String infixToPostfix(String exp) {
Stack<String> ops = new Stack<>();
StringBuilder postfix = new StringBuilder();
String[] tokens = exp.split("\\s+");

for (String token : tokens) {
if (token.equals("(")) {
// Bỏ qua dấu mở ngoặc
} else if (token.equals("+") || token.equals("-") ||
token.equals("*") || token.equals("/")) {
ops.push(token);
} else if (token.equals(")")) {
postfix.append(ops.pop()).append(" ");
} else {
postfix.append(token).append(" ");
}
}
return postfix.toString().trim();
}

Câu 3 (1,5 điểm)
a) Thêm khóa 6868 vào Max Heap `[-, 85, 75, 60, 40, 50, 30]`:
- Bước 1: Thêm 6868 vào vị trí cuối mảng (chỉ số 7): `[-, 85, 75, 60, 40, 50, 30, 68]`.
- Bước 2: Gọi `swim(7)`: Nút cha tại chỉ số ⌊7/2⌋=3\lfloor 7/2 \rfloor = 3 có giá trị 6060. Do 68>6068 > 60, hoán đổi 6868 và 6060.
→\to Mảng: `[-, 85, 75, 68, 40, 50, 30, 60]`.
- Bước 3: Gọi `swim(3)`: Nút cha tại chỉ số ⌊3/2⌋=1\lfloor 3/2 \rfloor = 1 có giá trị 8585. Do 68<8568 < 85, điều kiện Max Heap thỏa mãn. Dừng.
→\to Kết quả: `[-, 85, 75, 68, 40, 50, 30, 60]`.

b) Xóa phần tử lớn nhất (`delMax`) từ Heap trên:
- Bước 1: Đổi chỗ gốc (8585 tại index 1) với phần tử cuối (6060 tại index 7), giảm kích thước mảng còn 66. Xóa 8585.
→\to Mảng tạm: `[-, 60, 75, 68, 40, 50, 30]`.
- Bước 2: Gọi `sink(1)`: Gốc 6060 có con trái là 7575 (index 2) và con phải là 6868 (index 3). Con lớn nhất là 7575. Do 60<7560 < 75, hoán đổi 6060 và 7575.
→\to Mảng: `[-, 75, 60, 68, 40, 50, 30]`.
- Bước 3: Xét nút 6060 tại index 2: có con trái là 4040 (index 4) và con phải là 5050 (index 5). Con lớn nhất là 5050. Do 60>5060 > 50, điều kiện Max Heap thỏa mãn. Dừng.
→\to Kết quả: `[-, 75, 60, 68, 40, 50, 30]`.

Câu 4 (1,5 điểm)
a) Cây BST sau khi thêm chuỗi khóa `80, 20, 40, 30, 10, 100, 70, 90, 50`:

80
/ \
20 100
/ \ /
10 40 90
/ \
30 70
/
50

- 8080 là gốc.
- 20<80  ⟹  20 < 80 \implies rẽ trái.
- 40>20  ⟹  40 > 20 \implies rẽ phải của 2020.
- 30<40  ⟹  30 < 40 \implies rẽ trái của 4040.
- 10<20  ⟹  10 < 20 \implies rẽ trái của 2020.
- 100>80  ⟹  100 > 80 \implies rẽ phải của 8080.
- 70>40  ⟹  70 > 40 \implies rẽ phải của 4040.
- 90<100  ⟹  90 < 100 \implies rẽ trái của 100100.
- 50<70  ⟹  50 < 70 \implies rẽ trái của 7070.

b) Hàm đệ quy tính tổng các khóa:

int sumKeys(Node root) {
if (root == null) return 0;
return root.key + sumKeys(root.left) + sumKeys(root.right);
}

Câu 5 (1,0 điểm)
Thiết kế cấu trúc `UniStack`:
- Cấu trúc kết hợp:
- Danh sách liên kết kép (Doubly Linked List - DLL): Nút chứa giá trị chuỗi và 2 con trỏ `prev`, `next`. Con trỏ `head` trỏ tới đỉnh Stack.
- Bảng băm (`HashMap<String, Node>`): Lưu ánh xạ từ chuỗi giá trị tới nút chứa nó trong DLL.
- Thao tác `push(x)`:
- Kiểm tra `map.containsKey(x)`. Nếu đã tồn tại, lấy nút ra và ngắt liên kết khỏi DLL trong O(1)O(1).
- Tạo nút mới chứa `x`, chèn lên đầu DLL (`head`) trong O(1)O(1).
- Cập nhật địa chỉ nút vào `map.put(x, newNode)`.
- Thao tác `pop()`:
- Lấy giá trị chuỗi tại `head.val`.
- Xóa nút `head` khỏi DLL và xóa khóa tương ứng trong `map`.
- Trả về giá trị đã lấy.
- Độ phức tạp: Thời gian O(1)O(1) cho mỗi thao tác, bộ nhớ phụ O(N)O(N) đáp ứng hoàn toàn yêu cầu đề bài.

KHOA CÔNG NGHỆ THÔNG TIN

BỘ MÔN KHOA HỌC MÁY TÍNH

Đề ôn tập số 05

ĐỀ ÔN TẬP GIỮA KỲ HỌC PHẦN DSA

Môn: Cấu trúc dữ liệu và Giải thuật

Thời gian làm bài: 60 phút (không kể thời gian phát đề)

PHẦN I. TRẮC NGHIỆM (3,0 điểm)

Thí sinh chọn một phương án đúng duy nhất cho mỗi câu hỏi sau:

Câu 1. Giả sử thực hiện MM thao tác union/find trên cấu trúc dữ liệu Quick-Union có trọng số (Weighted Quick-Union) với NN đối tượng. Thời gian chạy tồi nhất tỉ lệ với:

A. N+Mlog⁡NN + M \log N

B. N+Mlog⁡∗NN + M \log^* N (hoặc N+Mlog⁡NN + M \log N)

C. M+N2M + N^2

D. M⋅NM \cdot N

Câu 2. Cấu trúc dữ liệu Hàng đợi (Queue) thường được ứng dụng trong thuật toán nào sau đây?

A. Thuật toán Duyệt theo chiều rộng (BFS)

B. Thuật toán Duyệt theo chiều sâu (DFS)

C. Đánh giá biểu thức bằng Stack

D. Sắp xếp Heapsort

Câu 3. Thuật toán sắp xếp nào sau đây có thời gian chạy trường hợp tốt nhất (Best case) là O(N)O(N)?

A. Selection Sort

B. Insertion Sort

C. Mergesort Top-down

D. Quicksort tiêu chuẩn

Câu 4. Giáo viên cần sắp xếp danh sách sinh viên: đầu tiên theo Nhóm thực hành, sau đó trong từng nhóm sắp xếp theo Tên ABC. Hỏi thuật toán sắp xếp được chọn bắt buộc phải có đặc tính gì nếu ta sắp xếp theo Tên trước rồi mới sắp xếp theo Nhóm thực hành?

A. Tính tại chỗ (In-place)

B. Tính ổn định (Stable)

C. Chạy trong thời gian O(N)O(N)

D. Đệ quy

Câu 5. Mức (Level) hay Độ sâu (Depth) của nút gốc trong cây nhị phân theo quy ước thông thường bằng bao nhiêu?

A. 00

B. 11

C. 22

D. −1-1

Câu 6. Kết quả duyệt cây BST theo thứ tự Postorder (Hậu tự) luôn thăm nút gốc ở vị trí nào?

A. Đầu tiên

B. Chính giữa

C. Cuối cùng

D. Tùy thuộc vào chiều cao cây

Câu 7. Phương pháp sắp xếp Trộn Bottom-up Mergesort thực hiện sắp xếp mảng mà KHÔNG sử dụng:

A. Mảng phụ `aux`

B. Phép so sánh

C. Đệ quy (sử dụng vòng lặp duyệt kích thước mảng con sz=1,2,4,8…sz = 1, 2, 4, 8\dots)

D. Phép gán

Câu 8. Cho mảng biểu diễn Min Heap: `[-, 5, 12, 10, 15, 20, 25]`. Giá trị của nút con phải của nút gốc là:

A. 1212

B. 1010

C. 1515

D. 2020

Câu 9. Trong thuật toán Quicksort, bước Phân chia mảng (Partitioning) tiêu chuẩn mất thời gian:

A. O(1)O(1)

B. O(log⁡N)O(\log N)

C. O(N)O(N)

D. O(Nlog⁡N)O(N \log N)

Câu 10. Trong cài đặt Stack bằng Danh sách liên kết đơn, thao tác `push(x)` và `pop()` thực hiện ở đầu danh sách có độ phức tạp thời gian là:

A. O(1)O(1)

B. O(log⁡N)O(\log N)

C. O(N)O(N)

D. O(N2)O(N^2)

Câu 11. Cho hai hàm f(N)=Nlog⁡2Nf(N) = N \log_2 N và g(N)=N1.5g(N) = N^{1.5}. Phát biểu nào sau đây đúng về cấp tăng?

A. f(N)f(N) tăng nhanh hơn g(N)g(N)

B. g(N)g(N) tăng nhanh hơn f(N)f(N)

C. Hai hàm có cùng cấp tăng

D. Không so sánh được

Câu 12. Cấu trúc Priority Queue cài đặt bằng Mảng đã sắp xếp tăng dần có độ phức tạp của thao tác `insert` và `delMax` lần lượt là:

A. O(1)O(1) và O(N)O(N)

B. O(N)O(N) và O(1)O(1)

C. O(log⁡N)O(\log N) và O(log⁡N)O(\log N)

D. O(1)O(1) và O(1)O(1)

Câu 13. Trong cây BST, thao tác `rank(key)` trả về giá trị gì?

A. Số lượng khóa trong cây nhỏ hơn `key`

B. Chiều sâu của `key`

C. Số lượng khóa trong cây lớn hơn `key`

D. Số con của nút chứa `key`

Câu 14. Trong thuật toán Dijkstra 2-stack để tính giá trị biểu thức số học, khi gặp dấu đóng ngoặc `)`, ta thực hiện thao tác gì?

A. Đẩy dấu `)` vào stack toán tử

B. Pop 1 toán tử từ stack toán tử, pop 2 giá trị từ stack giá trị, thực hiện phép tính rồi push kết quả trở lại stack giá trị

C. Bỏ qua dấu `)`

D. Xóa toàn bộ stack

Câu 15. Sự khác biệt cơ bản về nguyên lý giữa Selection Sort và Insertion Sort là gì?

A. Selection Sort tìm phần tử nhỏ nhất trong phần chưa sắp xếp để đưa về đúng vị trí; Insertion Sort chèn phần tử hiện tại vào vị trí đúng trong phần đã sắp xếp

B. Selection Sort có tính ổn định còn Insertion Sort thì không

C. Insertion Sort dùng O(N)O(N) bộ nhớ phụ còn Selection Sort dùng O(1)O(1)

D. Selection Sort chạy O(Nlog⁡N)O(N \log N) còn Insertion Sort chạy O(N2)O(N^2)

PHẦN II. TỰ LUẬN (7,0 điểm)

Câu 1 (1,5 điểm - Phân tích thuật toán).
Cho hàm `mergeTwo` dưới đây:

void mergeTwo(int a[], int aux[], int N) {
int lo = 0, mid = N / 2, hi = N - 1;
for (int k = lo; k <= hi; k++) aux[k] = a[k];
int i = lo, j = mid + 1;
for (int k = lo; k <= hi; k++) {
if (i > mid) a[k] = aux[j++];
else if (j > hi) a[k] = aux[i++];
else if (aux[j] < aux[i]) a[k] = aux[j++];
else a[k] = aux[i++];
}
}

a) Tính chính xác số lần truy nhập mảng (đọc/ghi trên `a` và `aux`) theo NN.
b) Cho biết độ phức tạp thời gian theo OO và Tilde (∼\sim) trong trường hợp tốt nhất và tồi nhất.

Câu 2 (1,5 điểm - Stack & Queue).
a) Cho Queue Q=[1,2,3,4,5]Q = [1, 2, 3, 4, 5] (đầu lấy phần tử là 11) và Stack SS rỗng. Viết đoạn code đảo ngược thứ tự các phần tử trong QQ.
b) Viết hàm `boolean areEqualStacks(Stack<Integer> s1, Stack<Integer> s2)` kiểm tra xem 2 Stack có giống hệt nhau về nội dung và thứ tự không mà không làm thay đổi trạng thái ban đầu của s1,s2s1, s2.

Câu 3 (1,5 điểm - Sắp xếp & Heap).
a) Cho mảng A=[32,15,7,28,4,19,30,22]A = [32, 15, 7, 28, 4, 19, 30, 22]. Minh họa bước Partition đầu tiên của Quicksort tiêu chuẩn (chốt là phần tử đầu tiên A[0]A[0]).
b) Minh họa các bước sắp xếp mảng A=[25,67,34,15,42,7,9]A = [25, 67, 34, 15, 42, 7, 9] bằng Insertion Sort.

Câu 4 (1,5 điểm - Cây BST).
a) Thêm các khóa 25,15,35,10,20,30,4025, 15, 35, 10, 20, 30, 40 vào cây BST rỗng. Vẽ cây kết quả.
b) Viết hàm đệ quy `int countSingleChildNodes(Node root)` đếm số lượng nút trong cây BST chỉ có đúng 1 nút con.

Câu 5 (1,0 điểm - Bài toán ứng dụng).
Thiết kế cấu trúc dữ liệu `Tournament` lưu trữ thông tin đấu thủ: `insert(name, score)`, `getScore(name)`, `getLead()`. Yêu cầu cả 3 hàm chạy thời gian O(log⁡N)O(\log N), bộ nhớ O(N)O(N).

--------- HẾT ĐỀ SỐ 5 ---------

Xem tất cả