Danh sách câu hỏi của đề

Câu hỏi: CSD201 Cấu trúc dữ liệu và giải thuật – Bộ ôn tập thi lại số 1

50 câu trắc nghiệm kèm lời giải của môn CSD201 - Cấu trúc dữ liệu và giải thuật, xếp đúng thứ tự trong đề.

Danh sách câu hỏi

20/50 câuCòn 30
ATrue
BFalse
Lời giải
Đáp án đúng: "True". Phát biểu đúng đúng định nghĩa của danh sách liên kết đơn: mỗi phần tử gồm phần dữ liệu và một liên kết trỏ tới phần tử kế tiếp, liên kết của phần tử cuối mang giá trị null. Chính chuỗi liên kết này giữ cho cấu trúc đứng vững dù các nút nằm rải rác trong bộ nhớ, khác với mảng phải chiếm một dải địa chỉ liên tục; đổi lại, vì chỉ có một liên kết xuôi nên danh sách đơn không đi lùi được, muốn lùi phải chuyển sang danh sách liên kết đôi với thêm trường prev. Phương án "False" chỉ đúng nếu phát biểu đòi thêm điều mà danh sách đơn không có, chẳng hạn liên kết hai chiều hay truy cập theo chỉ số trong một bước; nhưng phát biểu đã cho chỉ nêu dữ liệu và liên kết tới phần tử kế tiếp, không thừa cũng không thiếu.
Mở trang câu hỏi này →
An
Bn-1
Cn+1
D2n
Lời giải
Đáp án đúng: "n-1". Cây khung là đồ thị con nối hết n đỉnh mà không có chu trình, và một cây có n đỉnh luôn có đúng n-1 cạnh: bắt đầu từ một đỉnh, mỗi cạnh thêm vào phải kéo thêm đúng một đỉnh mới, nếu không nó nối hai đỉnh đã cùng thành phần và sinh chu trình. Trọng số không ảnh hưởng tới số cạnh, nên cây khung nhỏ nhất cũng chỉ khác ở việc chọn cạnh nào, không khác ở số lượng. "n" sai vì n cạnh trên n đỉnh đã vượt ngưỡng cây một cạnh, buộc phải có chu trình. "n+1" sai vì càng thừa hơn, hai cạnh dư tạo ít nhất hai chu trình độc lập. "2n" sai vì nó lớn gấp đôi số đỉnh, chỉ có nghĩa với đồ thị dày chứ không phải với cây khung; đây cũng là lý do Kruskal dừng ngay khi nhận đủ n-1 cạnh.
Mở trang câu hỏi này →
AFalse
BTrue
Lời giải
Đáp án đúng: "True". Trong danh sách liên kết đơn mỗi nút chỉ giữ liên kết tới nút sau, nên muốn chèn trước một nút cho trước phải tìm được nút liền trước nó, mà cách duy nhất là đi lại từ đầu danh sách, chi phí tỉ lệ với số nút. Ngược lại, chèn sau một nút đã có trong tay chỉ cần hai phép gán liên kết, còn chèn ở đầu chỉ cần cho nút mới trỏ vào head rồi dời head, cả hai đều tốn thời gian hằng số và không phụ thuộc độ dài danh sách. Vì vậy nhận định đúng cả hai nửa của nó. Trả lời "False" chỉ hợp khi danh sách có thêm liên kết lùi, tức danh sách liên kết kép, hoặc khi người ta dùng mánh chèn sau rồi đổi dữ liệu hai nút để giả lập phép chèn trước; với danh sách liên kết đơn thuần thì cả hai mệnh đề trong câu đều đứng vững.
Mở trang câu hỏi này →
AObject dequeue() { if(isEmpty()) return(null); Node p = head; head=head.next; if(head==tail) tail=null; return(p.info); }
BObject dequeue() { if(isEmpty()) return(null); Node p = head; head=head.next; return(p.info); }
CObject dequeue() { if(isEmpty()) return(null); Node p = head; head=head.next; if(head==null) tail=null; return(p.info); }
DObject dequeue() { if(isEmpty()) return(null); head=head.next; if(head.next==null) tail=null; return(head.info); }
Lời giải

Đáp án đúng: "Object dequeue() { if(isEmpty()) return(null); Node p = head; head=head.next;

Lời giải
if(head==null) tail=null;
return(p.info);

}". Hàng đợi cài bằng danh sách liên kết đơn lấy phần tử ra ở đầu, nên trình tự phải là giữ lại nút đầu để còn đọc dữ liệu, dời head sang nút kế tiếp, và vì tail vẫn trỏ tới nút vừa bị tách khi hàng đợi thành rỗng, phải kiểm head bằng null để đặt tail về null. "Object dequeue() { if(isEmpty()) return(null); Node p = head; head=head.next;

Lời giải
if(head==tail) tail=null;
return(p.info);

}" so head với tail: với hàng đợi hai phần tử, sau khi dời head thì head và tail cùng trỏ nút cuối nên nó xoá tail trong khi hàng đợi vẫn còn một phần tử; còn khi hàng đợi chỉ còn một phần tử thì head thành null mà tail vẫn trỏ nút cũ nên không được dọn. "Object dequeue() { if(isEmpty()) return(null); Node p = head; head=head.next; return(p.info); }" trả về đúng giá trị nhưng không bao giờ dọn tail, nên khi hàng đợi rỗng tail còn treo ở nút đã bị tách và lần thêm vào sau đó sẽ nối phần tử mới vào chỗ không còn ai trỏ tới. "Object dequeue() { if(isEmpty()) return(null); head=head.next;

Lời giải
if(head.next==null) tail=null;
return(head.info);

}" dời head trước khi đọc dữ liệu nên trả về phần tử thứ hai chứ không phải phần tử đầu, và khi hàng đợi chỉ còn một phần tử thì head thành null nên head.next gây lỗi truy cập null.

Mở trang câu hỏi này →
Alists
Bstacks
Carray
Dqueues
Lời giải
Đáp án đúng: "stacks". Cặp thao tác push và pop chính là giao diện chuẩn của ngăn xếp: push đặt phần tử lên đỉnh, pop lấy phần tử ở đỉnh ra, cả hai chỉ làm việc tại một đầu duy nhất nên cấu trúc hoạt động theo nguyên tắc vào sau ra trước. "queues" dùng cặp thao tác khác là enqueue thêm vào cuối và dequeue lấy ra ở đầu, làm việc ở hai đầu đối diện để giữ nguyên tắc vào trước ra trước. "lists" là cấu trúc tổng quát hơn, giao diện của nó nói về chèn và xoá ở một vị trí hay chỉ số bất kỳ, không bị giới hạn ở một đầu. "array" chỉ là vùng nhớ liên tục truy cập bằng chỉ số; nó thường được dùng làm chỗ chứa bên trong để hiện thực một ngăn xếp, nhưng bản thân mảng không có thao tác nào mang tên push hay pop.
Mở trang câu hỏi này →
A2, 1, 4, 3, 8, 9, 7
B4, 2, 8, 1, 3, 7, 9
C2, 1, 4, 3, 8, 7, 9
D2, 1, 4, 3, 7, 8, 9
Lời giải
Đáp án đúng: "4, 2, 8, 1, 3, 7, 9". Cây có gốc 5, bên trái là 2 với hai con 1 và 4 trong đó 4 có con trái 3, bên phải là 8 với hai con 7 và 9. Xoá bằng cách sao chép kéo giá trị nút liền trước, tức nút phải nhất của cây con trái, lên chỗ nút bị xoá rồi cắt nút ấy: từ 2 đi phải hết cỡ được 4, nên 4 lên làm gốc; nút 4 chỉ có con trái 3 nên khi cắt nó, 3 lên thay chỗ và thành con phải của 2. Cây mới có gốc 4 với hai con 2 và 8; 2 có hai con 1 và 3; 8 có hai con 7 và 9. Duyệt bề rộng cho 4, rồi 2 và 8, rồi 1, 3, 7, 9. Vì vậy "2, 1, 4, 3, 8, 7, 9" sai vì đó là kết quả của phép xoá bằng cách nối, treo cây con phải 8 vào nút 4 rồi đưa 2 lên làm gốc; "2, 1, 4, 3, 8, 9, 7" sai vì ngoài việc đưa 2 lên gốc nó còn in 9 trước 7, trong khi duyệt bề rộng lấy con trái trước con phải; "2, 1, 4, 3, 7, 8, 9" sai vì nó in 7 trước 8 dù 8 ở tầng ngay dưới gốc còn 7 ở tầng sâu hơn.
Mở trang câu hỏi này →
ANode q = new Node(x); q.next = p.next; p.next = q;
Bp.next = new Node(x); p=p.next;
CNode q = new Node(x); q.next = null; p.next = q;
DNode q = new Node(x); p.next = q; q.next = p.next;
Lời giải

Đáp án đúng: "Node q = new Node(x); q.next = p.next; p.next = q;". Thứ tự hai lệnh gán là điểm cốt yếu: trước hết cho nút mới nhận phần đuôi cũ bằng q.next = p.next, sau đó mới cho p trỏ sang nút mới; nhờ vậy không mắt nối nào bị mất và chi phí là hằng số. Bản "p.next = new Node(x); p=p.next;" ghi đè p.next trước khi lưu lại nút kế, nên toàn bộ phần sau p rơi khỏi danh sách. Bản "Node q = new Node(x); q.next = null; p.next = q;" biến nút mới thành nút cuối, cắt đứt mọi nút phía sau p dù đề nói rõ p có nút kế. Bản "Node q = new Node(x); p.next = q; q.next = p.next;" đảo thứ tự: sau lệnh đầu thì p.next đã là q, nên lệnh sau gán q.next = q tạo vòng tự trỏ và phần đuôi cũ mất hẳn.

Mở trang câu hỏi này →
AEvery complete binary tree is also a full binary tree.
BEvery binary tree is either complete or full.
CEvery full binary tree is also a complete binary tree.
DNo binary tree is both complete and full.
Lời giải
Đáp án đúng: "Every complete binary tree is also a full binary tree.". Theo quy ước mà đề nhắc, cây nhị phân full cũng là proper hay 2-tree, tức cây mà mọi nút trong đều có đúng hai con; còn cây complete là cây mà mọi mức đều được lấp kín. Khi mọi mức đã kín thì không nút trong nào thiếu con, nên cây complete tất yếu là cây full. Phương án "Every full binary tree is also a complete binary tree." sai theo chiều ngược: một cây mà mọi nút trong có hai con vẫn có thể lệch hẳn, chẳng hạn nhánh trái sâu bốn mức còn nhánh phải chỉ là một lá, lúc đó các mức không kín. Phương án "Every binary tree is either complete or full." sai vì dễ dựng cây không thuộc loại nào: gốc chỉ có con trái, con trái đó lại chỉ có con trái. Phương án "No binary tree is both complete and full." sai vì cây gồm một gốc và hai lá vừa kín mức vừa có nút trong đủ hai con.
Mở trang câu hỏi này →
A40
B35
C45
D39
E42
Lời giải
Đáp án đúng: "39". Sáu đỉnh cần đúng năm cạnh; chạy Kruskal theo trọng số tăng dần: B-C = 4 nhận, A-C = 6 nhận, C-D = 7 nhận, A-D = 8 bỏ vì nối hai đỉnh đã cùng một thành phần, E-F = 10 nhận (thành phần riêng), C-E = 12 nhận và lúc này cả sáu đỉnh đã chung một cây. Tổng 4 + 6 + 7 + 10 + 12 = 39. "40" sai vì nó dùng A-D = 8 thay cho C-D = 7 để kéo D vào cây, trong khi cạnh 7 rẻ hơn và cũng không tạo chu trình. "35" sai vì nó cộng năm cạnh rẻ nhất 4, 6, 7, 8, 10 mà không kiểm tra gì: A-D tạo chu trình, còn cặp E-F vẫn rời khỏi phần còn lại. "45" sai vì nó nối F bằng D-F = 16 thay cho E-F = 10, chọn đúng cạnh đắt nhất của đồ thị. "42" sai vì nó thêm A-B = 13, cạnh khép kín tam giác A-B-C, và như vậy vẫn còn một đỉnh chưa được nối vào cây.
Mở trang câu hỏi này →
Đề bài
int x = 13;
Node f = p.prev; //prev is a link to predecessor node
Node q = new Node(x);
q.prev = f; q.next = p;
f.next = q; p.prev = q;
A7 1 6 4 3 12 8 21 13
B7 1 6 4 3 13 12 8 21
C7 1 6 4 3 12 13 8 21
D7 13 1 6 4 3 12 8 21
E13 7 1 6 4 3 12 8 21
Lời giải
Đáp án đúng: "7 1 6 4 3 13 12 8 21". Đoạn mã lấy f là nút liền trước p, mà p trỏ vào nút 12 nên f là nút 3. Nút mới mang 13 được gắn prev vào f, next vào p, rồi f.next trỏ sang nó và p.prev cũng trỏ về nó, nên 13 nằm đúng giữa 3 với 12; nhờ có liên kết lùi mà việc chèn trước một nút chỉ tốn vài phép gán, không phải đi tìm nút tiền nhiệm. Dãy "7 1 6 4 3 12 13 8 21" đặt 13 sau 12, muốn vậy phải lấy f là p.next rồi nối vào phía sau. Dãy "7 1 6 4 3 12 8 21 13" đặt 13 ở cuối danh sách, đó là phép thêm vào nút cuối, không liên quan tới p. Dãy "7 13 1 6 4 3 12 8 21" chèn 13 vào sau nút đầu, chỉ đúng nếu f được gán bằng head. Dãy "13 7 1 6 4 3 12 8 21" đưa 13 lên đầu, tức phép chèn ở head kèm việc dời biến head, mà đoạn mã không chạm tới head.
Mở trang câu hỏi này →
Đề bài
       f(n) = 1;
2. if n > 2 then
       f(n) = f(n-1) + 2f(n-2)

What is the value of f(5) ?

A12
B11
C13
D10
Lời giải
Đáp án đúng: "11". Định nghĩa cho f(1) bằng 1 và f(2) bằng 1, còn với n lớn hơn 2 thì f(n) bằng f(n-1) cộng hai lần f(n-2). Tính dần từ dưới lên: f(3) bằng f(2) cộng 2 lần f(1), tức 1 cộng 2 bằng 3; f(4) bằng f(3) cộng 2 lần f(2), tức 3 cộng 2 bằng 5; f(5) bằng f(4) cộng 2 lần f(3), tức 5 cộng 6 bằng 11. "13" chính là 2 lần f(4) cộng f(3), tức đặt hệ số 2 vào sai hạng, nhân đôi giá trị liền trước thay vì giá trị cách hai bước. "10" ứng với f(4) cộng f(3) cộng 2, tức hiểu số 2 trong công thức là số hạng cộng thêm chứ không phải hệ số nhân với f(n-2). "12" không ứng với bước tính nào: dãy giá trị đúng là 1, 1, 3, 5, 11 nên giá trị tại 5 không thể là 12.
Mở trang câu hỏi này →
A1
B2
C4
D3
E5
Lời giải
Đáp án đúng: "2". Thuật toán tô màu tuần tự xếp đỉnh theo bậc giảm dần rồi gán cho mỗi đỉnh màu có số nhỏ nhất chưa bị đỉnh kề nào dùng. Với các cạnh A-B, A-C, A-D, A-G, B-C, B-E, C-E, E-G, E-F, D-F, bậc là A 4, E 4, B 3, C 3, D 2, F 2, G 2, nên thứ tự xét là A, E, B, C, D, F, G. A nhận màu 1. E không kề A (các cạnh của A chỉ tới B, C, D, G) nên E cũng nhận màu 1. B kề A màu 1 và E màu 1 nên phải lấy màu 2. C kề A, B, E với các màu 1, 2, 1 nên lấy màu 3. Tới D: D chỉ kề A màu 1 và F chưa tô, nên màu nhỏ nhất còn dùng được là 2, vậy D mang màu 2. "1" không được vì D kề A đã mang màu 1. "3" và "4" đều lớn hơn mức cần thiết, vì màu 2 chưa bị đỉnh kề nào của D chiếm nên thuật toán không bỏ qua nó. "5" càng xa, cả đồ thị này chỉ cần ba màu.
Mở trang câu hỏi này →
A7, 4, 5, 2, 8, 6, 3, 1
B1, 2, 4, 7, 5, 3, 8, 6
C7, 4, 2, 5, 1, 3, 8, 6
D1, 2, 4, 7, 5, 3, 6, 8
Lời giải
Đáp án đúng: "7, 4, 2, 5, 1, 3, 8, 6". Cây có gốc 1 với con trái 2 và con phải 3; 2 có hai con 4 và 5; 4 có con trái 7; 3 có con phải 6; 6 có con trái 8. In-order đi hết nhánh trái, in gốc, rồi đi nhánh phải. Nhánh trái của 1: vào 2 thì trước hết vào 4, trước 4 lại vào 7 nên in 7, rồi 4, rồi 2, rồi 5, được 7, 4, 2, 5. In gốc 1. Nhánh phải: 3 không có con trái nên in 3, rồi xuống 6 mà trước 6 phải in con trái 8, được 3, 8, 6. Vì vậy "7, 4, 5, 2, 8, 6, 3, 1" sai vì đó là dãy post-order, nó in 5 trước 2 và dồn gốc 1 xuống cuối; "1, 2, 4, 7, 5, 3, 6, 8" sai vì đó là dãy pre-order, mở đầu bằng gốc rồi mới xuống nhánh; "1, 2, 4, 7, 5, 3, 8, 6" sai vì nó cũng mở đầu bằng gốc 1 như pre-order, mà in-order không bao giờ in gốc trước khi vét xong nhánh trái.
Mở trang câu hỏi này →
14Consider the following function:5 lựa chọncó code
Đề bài
int fun(int n)
  {if (n < 0)
    return(fun(-n));
     else if(n<5)
      return(2);
       else
      return(n*fun(n/2));
  }

Which call will result in the most recursive calls?

Afun(1014);
Bfun(100);
Cfun(0);
Dfun(1012);
Efun(-1012);
Lời giải
Đáp án đúng: "fun(-1012);". Với đối số âm, hàm gọi thêm một lượt fun(-n) rồi mới bước vào chuỗi chia đôi, nên nó tốn đúng một lời gọi nhiều hơn số dương tương ứng. Chuỗi của 1012 là 1012, 506, 253, 126, 63, 31, 15, 7 rồi 3 và dừng vì 3 nhỏ hơn 5, tức 8 lời gọi đệ quy; fun(-1012) thêm bước đổi dấu nên có 9. Phương án "fun(1012);" chính là chuỗi 8 lời gọi vừa đếm, ít hơn đúng một bước. Phương án "fun(1014);" cũng chỉ được 8 vì 1014 chia đôi thành 507 rồi 253, nhập vào đúng chuỗi của 1012 từ số 253 trở đi. Phương án "fun(100);" chỉ có 5 lời gọi theo chuỗi 100, 50, 25, 12, 6, 3. Phương án "fun(0);" không gọi đệ quy lần nào vì 0 nhỏ hơn 5 nên hàm trả về 2 ngay.
Mở trang câu hỏi này →
ATail recursion is a special case of recursion in which the first operation of the function, is a recursive call.
BTail recursion is a special case of recursion in which the last operation of the function, the tail call, is a recursive call.
Lời giải
Đáp án đúng: "Tail recursion is a special case of recursion in which the last operation of the function, the tail call, is a recursive call.". Đệ quy đuôi được định nghĩa bằng vị trí của lời gọi: lời gọi đệ quy là việc CUỐI CÙNG hàm làm, sau nó không còn phép tính nào chờ kết quả trả về. Nhờ vậy khung hoạt động hiện tại không cần giữ lại, và trình biên dịch có thể thay lời gọi bằng một bước nhảy, biến đệ quy thành vòng lặp chạy với bộ nhớ ngăn xếp hằng số. Phương án "Tail recursion is a special case of recursion in which the first operation of the function, is a recursive call." đặt lời gọi ở đầu hàm; khi đó sau lời gọi vẫn còn phần thân phải chạy nên mỗi lần gọi đều phải giữ khung hoạt động lại, ngăn xếp lớn theo độ sâu đệ quy. Đó là đệ quy thường, chính dạng cho ta những bài như in ngược dãy số dư, và nó không hưởng được phép tối ưu lời gọi đuôi.
Mở trang câu hỏi này →
ANode p1,p2; p1 = p.prev; p2=p1.next; p2.prev = p1; p1.next = p2;
BNode p1,p2; p1 = p.prev; // prev is a link to previous node p2=p.next; p2.prev = p1; p1.next = p2;
CNode p1,p2; p1 = p.prev p2=p.next; p2.prev = p1; p1.next = p;
DNode p1,p2; p1 = p.prev p2=p.next; p2.prev = p; p1.next = p2;
Lời giải
Đáp án đúng: "Node p1,p2; p1 = p.prev; // prev is a link to previous node p2=p.next; p2.prev = p1; p1.next = p2;". Xoá một nút giữa danh sách liên kết đôi phải vá cả hai chiều: p1 giữ nút trước, p2 giữ nút sau, rồi p2.prev trỏ về p1 và p1.next trỏ tới p2, nhờ vậy không còn liên kết nào dẫn tới p theo cả hai hướng. "Node p1,p2; p1 = p.prev; p2=p1.next; p2.prev = p1; p1.next = p2;" sai vì p2 được lấy từ p1.next nên p2 chính là p; hai lệnh sau chỉ ghi lại đúng các liên kết cũ và danh sách không đổi. "Node p1,p2; p1 = p.prev p2=p.next; p2.prev = p1; p1.next = p;" sai vì liên kết tiến vẫn trỏ tới p, nên đi từ head vẫn gặp p và nút này chưa bị xoá. "Node p1,p2; p1 = p.prev p2=p.next; p2.prev = p; p1.next = p2;" sai đối xứng: chiều tiến đã vượt qua p nhưng chiều lùi của nút sau vẫn trỏ về p, danh sách hỏng tính nhất quán hai chiều.
Mở trang câu hỏi này →
17Consider the following function:4 lựa chọncó code
Đề bài
void printOut(int n)
 {if (n==0) return;
  System.out.print(n);
  printOut(n-1);
  System.out.println(n);
 }

What is the output when the statement printOut(3); is run?

A123321
B321321
C321123
D123123
Lời giải
Đáp án đúng: "321123". Hàm in n trước khi gọi printOut(n-1) rồi in n thêm một lần sau khi lời gọi ấy trở về, nên mỗi tầng góp hai lần in nằm ở hai phía của đệ quy. Lượt đi in 3, 2, 1 theo chiều giảm; tới printOut(0) thì lệnh return cắt ngay nên tầng ấy không in gì; lượt về in 1, 2, 3 theo chiều tăng. Dãy "123321" là ảnh ngược của kết quả đúng, nó ứng với việc đặt lệnh in thứ nhất sau lời gọi đệ quy và lệnh in thứ hai trước. Dãy "321321" lặp nửa giảm hai lần, như thể cả hai lệnh in đều nằm trước lời gọi. Dãy "123123" lặp nửa tăng hai lần, như thể cả hai lệnh in đều nằm sau lời gọi, lúc đó trên đường đi xuống không có gì được in.
Mở trang câu hỏi này →
A2
B4
C3
D5
Lời giải
Đáp án đúng: "4". Với quy ước gốc có chiều cao 1, mức thứ i của cây nhị phân chứa tối đa 2 lũy thừa i trừ 1 nút, nên cây chiều cao h chứa tối đa 2 lũy thừa h trừ 1 nút: chiều cao 3 chứa nhiều nhất 1 cộng 2 cộng 4 bằng 7 nút, thêm mức thứ tư tối đa 8 nút nữa thành 15 nút. Vì 14 lớn hơn 7, không thể gói 14 nút vào ba mức; vì 14 không vượt 15, bốn mức là đủ, nên chiều cao nhỏ nhất bằng 4. "2" chỉ chứa tối đa 3 nút nên quá nhỏ. "3" chứa tối đa 7 nút, còn thiếu 7 nút so với 14. "5" là chiều cao đạt được nhưng không phải nhỏ nhất, vì chỉ cần dồn 14 nút vào bốn mức là xong; chiều cao 5 mới bắt buộc khi số nút vượt 15.
Mở trang câu hỏi này →
A6, 3, 7, 1, 5, 8, 2
B6, 3, 7, 1, 5, 2, 8
C6, 3, 1, 2, 5, 7, 8
D6, 3, 7, 1, 2, 5, 8
Lời giải
Đáp án đúng: "6, 3, 7, 1, 5, 8, 2". Chèn 6, 7, 3, 1, 2, 5, 8 vào cây tìm kiếm nhị phân: 6 làm gốc; 7 lớn hơn 6 nên là con phải; 3 nhỏ hơn 6 nên là con trái; 1 nhỏ hơn 3 nên là con trái của 3; 2 nhỏ hơn 6, nhỏ hơn 3, lớn hơn 1 nên là con phải của 1; 5 nhỏ hơn 6 nhưng lớn hơn 3 nên là con phải của 3; 8 lớn hơn cả 6 và 7 nên là con phải của 7. Duyệt theo chiều rộng đọc từng mức từ trái sang phải: 6; rồi 3 và 7; rồi 1, 5 và 8; cuối cùng là 2 ở mức sâu nhất. "6, 3, 7, 1, 5, 2, 8" đặt 2 trước 8 dù 8 nằm ở mức thứ ba còn 2 ở mức thứ tư. "6, 3, 7, 1, 2, 5, 8" chen 2 ngay sau 1 theo lối đi sâu vào nhánh, trong khi 5 và 8 cùng mức với 1 nên phải đọc trước. "6, 3, 1, 2, 5, 7, 8" đi hết nhánh trái rồi mới sang nhánh phải, đó là duyệt theo chiều sâu chứ không theo mức.
Mở trang câu hỏi này →
AH, C, T
BH, A, B, C, T
CH, A, B, D, T
DH, B, D, T
Lời giải
Đáp án đúng: "H, A, B, C, T". Dijkstra mỗi bước kết nạp đỉnh có khoảng cách tạm nhỏ nhất rồi cập nhật theo các cung đi ra. Từ H, khoảng cách tạm là A bằng 4, C bằng 6, B bằng 7. Nhỏ nhất là A nên kết nạp A; cung A→B 1 hạ B xuống 4 + 1 = 5, cung A→D 6 cho D bằng 10. Giờ B bằng 5 nhỏ nhất nên kết nạp B; cung B→C 5 cho 5 + 5 = 10 không tốt hơn 6 nên C giữ nhãn 6, cung B→D 4 hạ D xuống 5 + 4 = 9. Tiếp theo C bằng 6 nhỏ hơn D bằng 9 nên kết nạp C; cung C→T 2 cho T bằng 8. Cuối cùng T bằng 8 nhỏ hơn D bằng 9 nên T được kết nạp và ta dừng. Vì vậy "H, C, T" sai vì ngay bước đầu A bằng 4 nhỏ hơn C bằng 6 nên A phải vào trước; "H, A, B, D, T" sai vì sau B thì C bằng 6 còn nhỏ hơn D bằng 9, và T được chọn với nhãn 8 qua C nên D không kịp vào; "H, B, D, T" sai vì B lúc đầu mang nhãn 7 lớn hơn A bằng 4, chỉ sau khi kết nạp A thì B mới hạ xuống 5.
Mở trang câu hỏi này →