Professional Documents
Culture Documents
CTDL&GT
CTDL&GT
struct node {
int data;
struct node* next;
} node;
Nếu head đang trỏ tới danh sách 3,7 thì gọi hàm func(head) danh sách sẽ là 7,3
Nếu head đang trỏ tới danh sách 3,7 thì gọi hàm func(head) danh sách sẽ là 3,7
Nếu head đang trỏ tới danh sách rỗng thì gọi hàm func(head) sẽ bị lỗi
Nếu head đang trỏ tới danh sách 3,7,6 thì gọi hàm func(head) danh sách sẽ là 6,7,3
Nếu head đang trỏ tới danh sách 3,7,6 thì gọi hàm func(head) danh sách sẽ là 7,6,3
Nếu head đang trỏ tới danh sách 3,7,6,5 thì gọi hàm func(head) danh sách sẽ là 7,6,5,3
Nếu head đang trỏ tới danh sách 3,7,6,5 thì gọi hàm func(head) danh sách sẽ là 5,6,7,3
struct NODE
{
int data;
struct NODE* next;
};
if (head == NULL) {
head = newNode;
return;
}
Nếu head đang trỏ tới NULL thì gọi hàm liên tiếp func(head,3), func(head,7) sẽ cho danh sách 3,7
Nếu head đang trỏ tới NULL thì gọi hàm liên tiếp func(head,3), func(head,7) sẽ cho danh sách
rỗng
nếu head đang trỏ tới danh sách gồm 3,4, việc gọi hàm func(head,7) sẽ cho danh sách 7,3,4
nếu head đang trỏ tới danh sách gồm 3,4, việc gọi hàm func(head,7) sẽ cho danh sách 3,4,7
nếu head đang trỏ tới danh sách gồm 3,4, việc gọi hàm func(head,7) sẽ cho danh sách 3,4
3.Đâu là các thao tác cơ bản mà 1 cấu trúc dữ liệu cần phải có
Duyệt
Tìm kiếm
Thêm
Xóa
Đảo ngược dãy
Copy - clone
4.Cho đoạn code xử lý danh sách liên kết đơn sau
struct NODE
{
int data;
struct NODE* next;
};
Nếu head đang trỏ tới NULL thì gọi hàm liên tiếp func(head,3), func(head,7) sẽ cho danh sách 7,3
Nếu head đang trỏ tới NULL thì gọi hàm liên tiếp func(head,3), func(head,7) sẽ cho danh sách
rỗng
nếu head đang trỏ tới danh sách gồm 3,4, việc gọi hàm func(head,7) sẽ cho danh sách 7,3,4
nếu head đang trỏ tới danh sách gồm 3,4, việc gọi hàm func(head,7) sẽ cho danh sách 3,4,7
nếu head đang trỏ tới danh sách gồm 3,4, việc gọi hàm func(head,7) sẽ cho danh sách 3,4
struct node {
int data;
struct node* next;
} node;
Nếu head đang trỏ tới danh sách 3,7 thì gọi hàm func(head) sẽ in ra 7 3
Nếu head đang trỏ tới danh sách 3,7 thì gọi hàm func(head) sẽ in ra 3 7
Nếu head đang trỏ tới danh sách rỗng thì gọi hàm func(head) sẽ bị lỗi
Nếu head đang trỏ tới danh sách 3,7,3 thì gọi hàm func(head) sẽ in ra 3 7 3
nếu head đang trỏ tới danh sách gồm 3,4, việc gọi hàm func(head) sẽ cho danh sách 3
7.Điểm khác biệt giữa cấu trúc danh sách liên kết đơn và mảng là
Trong danh sách liên kết đơn, mỗi phần tử phải có ít nhất 1 trường kiểu con trỏ
Danh sách liên kết đơn có thể di chuyển - duyệt theo nhiều hướng
Danh sách liên kết đơn chỉ cấp phát và lưu trữ đủ các phần tử hiện có
Thêm/xóa với danh sách liên kết đơn chỉ cần xử lý với con trỏ, không cần di chuyển phần tử
Danh sách liên kết đơn luôn tiết kiệm bộ nhớ hơn mảng
Muốn truy cập vào danh sách luôn phải có địa chỉ phần tử đầu tiên
Thêm/xoá phần tử trong danh sách liên kết đơn có chi phí thấp hơn so với mảng trong trường
hợp tổng quát
8.Cho cấu trúc 1 danh sách liên kết đơn như sau
struct node {
int data;
struct node* next;
} node;
9.Cho cấu trúc 1 danh sách liên kết đơn như sau
struct node {
int data;
struct node* next;
} node;
struct node {
int data;
struct node* next;
} node;
Nếu head đang trỏ tới danh sách 3,7 thì gọi hàm func(head) sẽ in ra 7 3
Nếu head đang trỏ tới danh sách 3,7 thì gọi hàm func(head) sẽ in ra 3 7
Nếu head đang trỏ tới danh sách rỗng thì gọi hàm func(head) sẽ bị lỗi
Nếu head đang trỏ tới danh sách 3,7,3 thì gọi hàm func(head) sẽ in ra 3 7 3
nếu head đang trỏ tới danh sách gồm 3, việc gọi hàm func(head) sẽ bị lỗi
11.Để lưu trữ một danh sách n số nguyên với số lượng n tối đa có thể lên
tới 1tr (số lượng thực sự biến động trong quá trình dùng) thì nên dùng
CTDL nào để tiết kiệm bộ nhớ nhất
Mảng cấp phát 1 lần 1tr phần tử
Mảng động - hoặc vector
Danh sách liên kết đơn
Tất cả các phương án trên đều tiết kiệm bộ nhớ như nhau
12.struct Node là cấu trúc đã được định nghĩa để lưu trữ 1 nút của danh
sách liên kết, với dữ liệu 1 nút là kiểu DATATYPE
*head là con trỏ trỏ tới đầu danh sách liên kết
Code thực hiện với C/C++
Khi thêm 1 phần tử vào danh sách trong trường hợp tổng quát cần định nghĩa hàm là: void
insertNode (struct Node *head, DATATYPE data)
Khi thêm 1 phần tử vào danh sách trong trường hợp tổng quát cần định nghĩa hàm là: void
insertNode (struct Node **head, DATATYPE data)
Khi thêm 1 phần tử vào danh sách trong trường hợp tổng quát cần định nghĩa hàm là: struct
Node* insertNode (struct Node *head, DATATYPE data)
Khi thêm 1 phần tử vào danh sách trong trường hợp tổng quát cần định nghĩa hàm là: struct Node
insertNode (struct Node *head, DATATYPE data)
13.Bạn cần lưu trữ thông tin các sản phẩm trong giỏ hàng của mỗi khác
hàng khi mua sắm trên website, bạn sẽ
Dùng mảng để lưu trữ thông tin vì tìm kiếm thông tin sản phẩm trong giỏ hàng nhanh hơn
Dùng mảng để lưu trữ thông tin giỏ hàng vì duyệt khi checkout nhanh hơn
Dùng danh sách liên kết đơn để lưu trữ vì tối ưu bộ nhớ hơn
Dùng danh sách liên kết đơn để lưu trữ vì thêm và xóa sản phẩm dễ dàng hơn
Dùng mảng để lưu trữ vì thêm và xóa sản phẩm dễ dàng hơn
14.Với mảng kích thước biến đổi và giả sử ban đầu mảng cấp phát với 1
phần tử thì khi thêm lần lượt n phần tử vào mảng ta sẽ cần giãn mảng tối
đa bao nhiêu lần
n
logn
sqrt(n)
n/2
loglogn
15.So với mảng truyền thống thì kiểu vector trong C++ STL có đặc điểm gì
nổi bật
Không cần khai báo số lượng phần tử trước
Tự động thay đổi kích thước tùy vào nhu cầu sử dụng
Hỗ trợ một số hàm sẵn để xử lý
Thời gian thực hiện thêm hoặc xóa không phải hằng số
Trong trường hơp tổng quát vector tiết kiệm bộ nhớ hơn mảng truyền thống
17.Cho đoạn code quản lý mảng cấp phát động ở trong C như sau, các
đoạn còn thiếu cần điền gì?
int n;
printf("Enter the size of the array: ");
scanf("%d", &n);
// Kiểm tra xem việc cấp phát bộ nhớ có thành công không
if (B) {
printf("Memory allocation failed.\n");
return 1; // Kết thúc chương trình với mã lỗi 1
}
// Xử lý mảng
......
A : (double*)malloc(n * sizeof(double))
A: (double)malloc(n * sizeof(double))
A: (double*)malloc(n * sizeof(double*))
B: arr != NULL
B: arr == NULL
B: arr = NULL
C: delete(arr)
C: free(arr)
C :free(*arr)
19.Cho đoạn code xử lý mảng cấp phát nhiều lần trong C sau, cần điền gì
vào chỗ trống
int n;
printf("Enter the size of the array: ");
scanf("%d", &n);
arr = B;
if (arr == NULL) {
printf("Memory reallocation failed.\n");
return 1;
}
// XỬ LÝ MẢNG
....
// Giải phóng bộ nhớ sau khi sử dụng xong
C;
A: (double*)malloc(n * sizeof(double))
A: (double)malloc(n * sizeof(double*))
A: (double)malloc(n)
B: (double*)realloc(arr, newSize * sizeof(double*))
B: (double)realloc(arr, newSize * sizeof(double))
B: (double*)realloc(arr, newSize * sizeof(double))
B: (double*)malloc(arr, newSize * sizeof(double))
C: free(arr)
free(&arr)
20.Cho cấu trúc 1 danh sách liên kết đơn như sau
struct node {
int data;
struct node* next;
} node;
A: 0
A: 1
B: current != NULL
B: current->data != k
C: current = NULL
C: current = current->next
Sau khi xử lý hết xâu đầu vào thì lần lượt lấy từng phần tử trong stack ra và in ra màn hình
Nếu áp dụng thuật toán trên vào xâu đầu vào thì sẽ thu được gì
xâu đầu vào INC12 sẽ in ra INC12
xâu đầu vào INC12 sẽ in ra INC21
xâu đầu vào INC12 sẽ in ra 21INC
xâu đầu vào INC12 sẽ in ra 12CNI
xâu đầu vào INC12 sẽ in ra 12INCCNI
Nếu danh sách hiện tại là 1,3,-5,7 thì sau khi gọi hàm func danh sách sẽ chỉ còn 1,3,7
Nếu danh sách hiện tại là NULL thì khi gọi hàm func sẽ lỗi
Nếu danh sách hiện tại là -3 thì khi gọi hàm func danh sách sẽ là -3
Nếu danh sách hiện tại là -3,-5,-7,0 thì khi gọi hàm func danh sách sẽ là NULL
4.Giả sử bạn thêm lần lượt các phần tử số nguyên vào 1 stack và mỗi thao
tác thêm vào bạn cần biết giá trị lớn nhất trong các phân tử hiện tại là bao
nhiêu
VD.
push(5) --> giá trị lớn nhất hiện tại là 5
push(7) --> giá trị lớn nhất hiện tại là 7
push(3) --> giá trị lớn nhất hiện tại là 7
pop() --> giá trị lớn nhất hiện tại là 7
pop() --> giá trị lớn nhất hiện tại là 5
pop() --> giá trị lớn nhất không tồn tại (do stack rỗng)
5.Đâu là thao tác để kiểm tra phần tử hiện tại (đang trỏ bởi con trỏ p) đã ở
cuối danh sách trong trường hợp danh sách liên kết đơn nối vòng (đầu
danh sách là head)
Danh sách khác rỗng và có ít nhất 1 phần tử
p==head
p->next == NULL
p==NULL
p->next == head
p->next->next == head->next
6.Trong danh sách liên kết đôi nối vòng đâu là khẳng định đúng
Nếu dùng nút giả thì danh sách rỗng khi head->next == head hoặc head->prev = head
Nếu không dùng nút giả thì danh sách rỗng khi head->next == NULL
Nếu dùng nút giả thì p là phần tử cuối danh sách khi p->next == head hoặc head->prev = p
Nếu không dùng nút giả thì p là phần tử cuối danh sách khi p->next == head hoặc head-
>prev = p
7.Hàm giải phóng bộ nhớ của các phần tử trong danh sách liên kết này có
vấn đề gì?
8.Khẳng định nào sau đây về kiểu dữ liệu Stack là đúng (Stack trong STL và
trong Java)
Các thao tác thêm và lấy ra có thời gian O(1)
Thao tác tìm kiếm phần tử có thời gian O(n)
Thao tác tìm kiếm phần tử cũng có thời gian O(1)
Thao tác kiểm tra stack số lượng phần tử hiện có trong Stack có thời gian O(n)
Thao tác trả về số lượng các phần tử hiện có trong Stack là O(1)
return count;
}
Nếu danh sách hiện tại là 1,3,-5,7 thì sau khi gọi hàm func sẽ trả về giá trị 2
Nếu danh sách hiện tại là NULL thì khi gọi hàm func sẽ lỗi
Nếu danh sách hiện tại là -3 thì khi gọi hàm func trả về giá trị 1
Nếu danh sách hiện tại là -3,-5,-7,0 thì khi gọi hàm func sẽ trả về giá trị 4
Nếu danh sách hiện tại là -3,-5,-7,0 thì khi gọi hàm func sẽ bị lỗi
Nếu danh sách hiện tại là 1,3,-5,7 thì sau khi gọi hàm func danh sách sẽ chỉ còn 7,-5,3,1
Nếu danh sách hiện tại là NULL thì khi gọi hàm func sẽ lỗi
Nếu danh sách hiện tại là -3 thì khi gọi hàm func danh sách sẽ là -3
Nếu danh sách hiện tại là -3,-5,-7,0 thì khi gọi hàm func danh sách sẽ là 0
Nếu danh sách hiện tại là -3,-5,-7,0 thì khi gọi hàm func danh sách sẽ là 3
struct DNODE
{
int data;
struct DNODE* next, * prev;
};
if (B) {
*head = pnew;
}
else // ngươc lại gắn pnew vào vị trí thích hợp
{
C;
D;
E;
}
}
Nếu danh sách hiện tại là 1,3,-5,7 thì sau khi gọi hàm func danh sách sẽ là -5,7,3,1
Nếu danh sách hiện tại là NULL thì khi gọi hàm func sẽ lỗi
Nếu danh sách hiện tại là -3 thì khi gọi hàm func danh sách sẽ là -3
Nếu danh sách hiện tại là -3,-5,-7,0 thì khi gọi hàm func danh sách sẽ là 0,-3,-5,-7
Nếu danh sách hiện tại là -3,-5,-7,0 thì khi gọi hàm func sẽ bị lỗi
Nếu danh sách hiện tại là 1,3,-5,7 thì sau khi gọi hàm func các phần tử được in ra sẽ là 3,7
Nếu danh sách hiện tại là 1,3,-5,7 thì sau khi gọi hàm func các phần tử được in ra sẽ là 1, -5
Nếu danh sách hiện tại là -3 thì khi gọi hàm func các phần tử được in ra sẽ là -3
Nếu danh sách hiện tại là -3,-5,-7, 4,0 thì khi gọi hàm func các phần tử được in ra sẽ là -3,-5,4
16.Cho biểu thức dạng hậu tố sau, giá trị của biểu thức tính được sẽ là (các
toán tử là 2 ngôi)
483++*3-1++54-
Biểu thức bị sai
52
53
47
17.Giả sử ta sẽ thêm vào stack các chữ cái theo 1 thứ tự thêm là A B C D E F,
tuy nhiên giữa các lệnh thêm vào này lại đan xem các lệnh lấy ra.
Vậy thứ tự nào có thể là thứ tự lấy ra đúng trong các thứ tự sau
ABCDEF
ABCDFE
BCDEFA
ACDBEF
CDEFAB
18.Khi cài đặt cấu trúc dữ liệu ngăn xếp - Stack, đâu là khẳng định đúng
Cuối mảng là đỉnh của ngăn xếp khi cài đặt dùng mảng
Đầu mảng là đỉnh ngăn xếp khi cài đặt dùng mảng
Đầu danh sách liên kết đơn là đỉnh ngăn xếp khi cài đặt dùng DSLK đơn
Cuối danh sách liên kết đơn là đỉnh ngăn xếp khi cài đặt dùng DSLK đơn
19.Thao tác xóa 1 phần tử có giá trị x trong danh sách liên kết đơn sẽ có chi
phí trong trường hợp tốt nhất là
O(1)
O(logn)
O(n)
Không có lựa chọn nào là đúng
20.Đối với danh sách liên kết đôi thông thường, khi thêm phần tử vào sau
một phần tử đã có trong danh sách (đang trỏ bởi p) đâu là những công việc
cần làm
Cần kiểm tra phần tử p có phải cuối danh sách hay không
Cần kiểm tra phần tử p có phải đầu danh sách hay không
Cần kiểm tra danh sách hiện tại có rỗng
Cần kiểm tra p có rỗng
1.Cho biểu thức dạng trung tố sau, dạng hâu tố tương ứng sẽ là gì
(3+a-b)+5-2+6/c
(1 Point)
3ab-+52-+6c/+
3ab-+5+2-6c/+
3a+b-52-+6/+
3a+b-5+2-6c/+
2.Làm thế nào để có thể mô phỏng các thao tác của 1 stack dùng 2 hàng
đợi? Khẳng định nào là đúng
Không thể mô phỏng được vì hàng đợi không thể đảo được thứ tự
vẫn mô phỏng được, tuy nhiên mỗi lần lấy ra sẽ có chi phí O(n)
Mỗi lần thêm vào ta sẽ chỉ thêm vào hàng đợi đang có phần tử, hàng đợi còn lại dùng để hỗ
trợ lấy ra
Khi thêm mới ta luôn thêm vào hàng đơi đang trống, khi lấy ra thì lấy tại hàng đơi đang có phần tử
Luôn có 1 hàng đợi trống và 1 hàng đợi chứa các phần tử, hai hàng đợi không thể đồng thời
có phần tử
3.struct Node {
int data;
struct Node *next;
};
if (C) {
D;
}
free(temp);
return item;
}
A :q->front
A: q->rear
B: q->front->next
B: temp->next
C : q->front == NULL
C : q->rear == NULL
D: q->rear = NULL
D: q->front = NULL
A: q->front = 0
A: q->rear = 0
B: (q->rear + 1) % MAX_SIZE
B: (q->rear + 1)
B: (q->front + 1) % MAX_SIZE
6.Trong ý tưởng mô phỏng thao tác của 1 hàng đợi dùng 2 stack thì đâu là
khẳng định đúng
Việc thêm vào và lấy ra chỉ diễn ra tại 1 stack, stack còn lại chỉ là phụ
Luôn thêm vào tại Stack S1 và lấy ra tại stack S2
Nếu khi lấy ra mà Stack S2 rỗng thì sẽ lấy tại stack S1
Nếu khi thêm vào mà Stack S1 đang có phần tử thì sẽ thêm vào Stack S2
Nếu khi lấy ra mà Stack S2 rỗng thì ta sẽ lấy 1 phần tử của S1 đưa sang S2, sau đó lấy tại S2
7.Mảng dạng "vòng" trong cài đặt hàng đợi là mảng có đặc điểm gì
Bộ nhớ vật lý trên máy là mảng 1 chiều
Bộ nhớ vật lý trên máy là mảng 2 chiều
Bộ nhớ vật lý trên máy tạo thành hình vòng tròn
Duyệt hết phần tử cuối sẽ quay ngược về đầu mảng
Sử dụng bộ nhớ một cách tối ưu hơn so với các cài đặt dùng mảng thông thường
struct Queue {
int items[MAX_SIZE];
int front1, rear1; // Front và rear của hàng đợi thứ nhất
int front2, rear2; // Front và rear của hàng đợi thứ hai
};
9.Nếu cài đặt hàng đợi ưu tiên bằng các cấu trúc dữ liệu cơ bản thì
Thao tác them và lấy ra sẽ có thời gian O(n) nếu cài đặt bằng mảng
Thao tác them vào có thời gian O(n) và lấy ra sẽ có thời gian O(1) nếu cài đặt bằng mảng
Thao tác them và lấy ra sẽ có thời gian O(n) nếu cài đặt bằng danh sách liên kết
Thao tác them vào có thời gian O(n) và lấy ra sẽ có thời gian O(1) nếu cài đặt bằng danh sách
liên kết
10.Trong bài toán kiểm tra thẻ tag trong file html hoặc XML có hợp lệ hay
không (thẻ mở phải có thẻ đóng, trừ 1 số thẻ đặc biệt) dùng stack, đâu là
khẳng định đúng
Chỉ lưu trữ Stack bằng danh sách liên kết đơn
Chỉ lưu trữ Stack bằng mảng
Mỗi phần tử của Stack sẽ có thông tin mã thẻ (VD. thẻ body, p, a,..) lưu trữ bằng xâu ký tự
Lưu trữ bằng Mảng hay Danh sách liên kết đơn đều được
Độ phức tạp thời gian là O(n) trong trường hợp tồi nhất
11.Trong cài đặt hàng đợi dùng danh sách móc nối, việc sử dụng thêm con
trỏ rear - trỏ vào cuối danh sách có tác dụng là
Thêm phần tử vào cuối danh sách nhanh hơn
Đếm số phần tử trong danh sách nhanh hơn
Để phân biệt khi hàng đợi đầy và rỗng dễ dàng hơn
Để lấy phần tử khỏi hàng đợi dễ dàng hơn
12.Trong máy in mạng, để quản lý các công việc in đến từ các máy trong
LAN thì printer spooling đó nên tổ chức hàng đợi như thế nào?
Nên tổ chức hàng đợi bằng mảng với số lượng phần tử hàng đợi bằng số lượng máy tính trong LAN
Nên tổ chức hàng đợi dùng danh sách liên kết đơn để tối ưu bộ nhớ
Hàng đợi chỉ cần chứa địa chỉ IP máy yêu cầu in
Hàng đợi cần chứa nội dung công việc cần in
// Nếu Stack rỗng sau khi duyệt qua toàn bộ chuỗi HTML, thì các thẻ HTML hợp lệ
int result = isEmpty(stack);
free(stack->items);
free(stack);
return result;
}
14.// Hàm kiểm tra tính hợp lệ của các thẻ HTML
int isValidHTMLTags(char *html) {
struct Node *stack = NULL;
// Nếu Stack còn phần tử sau khi duyệt xong, thì các thẻ HTML không hợp lệ
if (!isEmpty(stack)) {
return 0;
}
return 1;
}
Hàm trên check được mọi loại thẻ html
isValidHTMLTags("<div><p>Hello, world!</p></div>") trả về giá trị 1
isValidHTMLTags("<div><p>Hello, world!</div>") trả về giá trị 1
isValidHTMLTags("<div><p>Hello, world!</div>") trả về giá trị 0
15.Cài đặt 2 hàng đợi chỉ dùng 1 mảng
struct Queue {
int items[MAX_SIZE];
int front1, rear1; // Front và rear của hàng đợi thứ nhất
int front2, rear2; // Front và rear của hàng đợi thứ hai
};
if (q->front1 == A) {
q->front1 = 0;
}
q->rear1 = B;
q->items[q->rear1] = item;
}
(1 Point)
A :-1
A: 0
B: (q->rear1 + 1) % MAX_SIZE
B: q->rear1 + 1
C: MAX_SIZE-1
C: MAX_SIZE
D: (q->rear2 - 1 + MAX_SIZE)
D: (q->rear2 - 1)
16.struct Node {
int data;
struct Node *next;
};
if (isEmpty(q)) {
B;
C;
return;
}
D;
q->rear = temp;
}
A :front->next = NULL
A: temp->next = NULL
B: q->front = temp
B: q->front = NULL
C : q->rear = temp
C : q->rear = NULL
D: q->rear->next = temp
D: q->rear= temp
Lặp lại công việc sau cho tới khi Stack rỗng
+ Lấy phần tử ở đỉnh Stack ra
+ In phần tử đó ra màn hình
18.Trong thuật toán chuyển biểu thức dạng trung tố sang dạng hậu tố
dùng Stack thì khẳng định nào sau đây là đúng
Stack dùng để chưa các toán hạng
Stack dùng để chứa toán tử
Stack dùng để chứa toán tử và dấu (
Stack dùng để chứa cả toán tử và toán hạng và dấu (
Stack dùng để chứa toán tử và dấu ( )
19.// Hàm kiểm tra tính hợp lệ của các thẻ HTML
int isValidHTMLTags(char* html) {
struct Node* stack = NULL;
// Duyệt qua từng ký tự trong chuỗi HTML
char* token = strtok(html, ">"), * subToken;
while (token != NULL) {
subToken = strchr(token, '<');
if (subToken == NULL) return 0;
subToken++;
// Nếu token là thẻ mở, thêm nó vào Stack
if (subToken[0] != '/') {
push(&stack, subToken);
printf("push %s\n", subToken);
}
// Nếu token là thẻ đóng
else if (subToken[0] == '/') {
// Kiểm tra xem Stack có rỗng không
if (isEmpty(stack)) {
return 0;
}
// Lấy thẻ mở khỏi Stack và so sánh tên thẻ
char* openTag = pop(&stack);
printf("Pop %s\n", openTag);
if (openTag == NULL || strcmp(openTag, subToken+1) != 0) {
return 0;
}
}
token = strtok(NULL, ">");
}
// Nếu Stack còn phần tử sau khi duyệt xong, thì các thẻ HTML không hợp lệ
if (!isEmpty(stack)) {
return 0;
}
return 1;
}
Hàm trên check được mọi loại thẻ html
isValidHTMLTags("<div><p>Hello, world!</p></div>") trả về giá trị 1
isValidHTMLTags("<div><p>Hello, world!</div>") trả về giá trị 1
isValidHTMLTags("<div><p>Hello, world!</div>") trả về giá trị 0
isValidHTMLTags("Hello, world!</p></div>") trả về giá trị 0
isValidHTMLTags("Hello, world!</p></div>") trả về giá trị 1
Time:
54:07
14/18
Trong các phương án biểu diễn cây tổng quát, giả sử ta biết trước số lượng
nút thì phương án nào tiết kiệm bộ nhớ nhất: Biển diễn qua danh nhãn
nút cha, biểu diễn qua danh sách nút con, biểu diễn qua con đầu tiên và
anh chị em kế tiếp
Biển diễn qua danh sách nhãn nút cha
Cho cây nhị phân tổng quát với root như hình
Hàm sau sẽ in ra gì
A, C, B, E, F, G, H, D, I, J, K, L,
C, G, H, E, F, B, J, K, L, I, D, A
Cho khai báo hàng đợi ưu tiên cài đặt bằng danh sách liên kết đơn sau
// Khai báo cấu trúc phần tử của hàng đợi
typedef struct Node {
int data;
int priority;
struct Node* next;
} Node;
if (isEmpty(queue) || A) {
B;
queue->front = newNode;
} else {
Node* current = queue->front;
while (current->next != NULL && C) {
current = current->next;
}
D;
current->next = newNode;
}
}
B: newNode->next = queue->front->next
B: newNode->next = queue->front
D: newNode->next = current
D: newNode->next = current->next
nút giữa
nút lá
nút rìa
nút trong
nút đỉnh
Cho cây nhị phân tổng quát với root như hình
Hàm sau sẽ trả về gì
int func(struct TNODE *root)
{
if(root==NULL) return 0;
if(root->firstChild==NULL) return 0;
struct TNODE *nextBrother = root->firstChild;
int max = -1, cur;
while(nextBrother!=NULL)
{
cur = func(nextBrother);
if(cur>max)max=cur;
nextBrother=nextBrother->nextSibling;
}
return 1+max;
}
11
Trong duyệt cây tổng quát, nếu nút lá luôn được xử lý đầu tiên thì quá
trình duyệt này có thể là
duyệt theo thứ tự trước
trong khi duyệt cây, dữ liệu tại gốc được xử lý sau khi xử lý hết tại các nút
con của nó. Thuật toán duyệt này được gọi là
duyệt theo thứ tự trước
duyệt tuần tự
Cho cây nhị phân tổng quát với root như hình
Hàm sau sẽ trả về gì
12
3
9
Để in ra các nút trên cây theo thứ tự lần lượt nút gốc, sau đó tới các nút
gần gốc trước, sau đó tới các nút xa hơn thì thuật toán duyệt cây đó ta cần
dùng thêm cấu trúc dữ liệu phụ nào
ngăn xếp
hàng đợi
gọi đệ quy, không cần dùng thêm cấu trức dữ liệu phụ
dùng vòng lặp và không cần dùng thêm cấu trúc dữ liệu phụ
10
Cho khai báo hàng đợi ưu tiên dùng mảng sau, cần điền gì vào chỗ khuyết
// Khai báo cấu trúc phần tử của hàng đợi
typedef struct {
int data;
int priority;
} Element;
int index = A;
while (index > 0 && B< priority) {
queue->elements[index] = queue->elements[index - 1];
C;
}
queue->elements[index].data = data;
queue->elements[index].priority = priority;
D;
}
A : queue->size
A: MAX_SIZE
A: 0
B: queue->elements[index].priority
B: queue->elements[index - 1].priority
B: queue->elements[MAX_SIZE- 1].priority
C : index--
C: index++
C: index=index-1
D: queue->size++
D: queue->size
11
Để tạo ra một cây nhị phân đầy đủ chiều cao h, số lượng nút cần phải có là
bao nhiêu
2^h
(2^(h+1))-1
2*h+1
2*(h+1)
12
root = createNewNode('A');
addNewChild(root, 'B');
addNewChild(root, 'H');
addNewChild(root, 'I');
addNewChild(root->firstChild, 'C');
addNewChild(root->firstChild->nextSibling, 'F');
addNewChild(root->firstChild->nextSibling, 'G');
addNewChild(root->firstChild->firstChild, 'D');
addNewChild(root->firstChild->firstChild, 'E');
return root;
}
I là con của G
E là con của B
Độ sâu của B là 2
Độ sâu của I là 1
Độ cao của A là 2
Nếu cài đặt hàng đợi ưu tiên bằng các cấu trúc dữ liệu cơ bản thì
Thao tác thêm và lấy ra sẽ có thời gian O(n) nếu cài đặt bằng mảng
Thao tác thêm vào có thời gian O(n) và lấy ra sẽ có thời gian O(1) nếu cài đặt bằng mảng
Thao tác thêm và lấy ra sẽ có thời gian O(n) nếu cài đặt bằng danh sách liên kết
Thao tác thêm vào có thời gian O(n) và lấy ra sẽ có thời gian O(1) nếu cài đặt bằng danh sách
liên kết
14
Cho cây nhị phân tổng quát với root như hình
Hàm sau sẽ trả về giá trị gì
nếu root là A
Cho khai báo hàng đợi ưu tiên cài đặt bằng danh sách liên kết đơn sau
// Khai báo cấu trúc phần tử của hàng đợi
typedef struct Node {
int data;
int priority;
struct Node* next;
} Node;
// Khai báo cấu trúc của hàng đợi ưu tiên
typedef struct {
Node* front;
} PriorityQueue;
A: PriorityQueue queue
A: PriorityQueue* queue
B: queue
B: queue->front
C: temp->data
C: queue->front->data
D: temp->next
D: queue->front->next
16
Chiều cao/độ sâu của của cây được tính như thế nào
là đường đi từ gốc tới lá dài nhất
17
Cho cây nhị phân tổng quát với root như hình
Hàm sau sẽ in ra gì
root là A và k = 1 sẽ in ra C
root là A và k = 1 sẽ in ra D, B, C
root là A và k = 2 sẽ in ra E, F, I
root là B và k = 3 sẽ in ra G, H
quan hệ cha-con
1
Cho hàm sau, điền gì vào chỗ khuyết ?
A: root->label=label
A: root->label==label
B: left!= NULL
B: left== NULL
C: root->right
C: root->left
2
Cho hàm sau, khi áp dụng với đầu vào là 2 cây trên thì kết quả trả về sẽ là
gì?
0
1
Hàm lỗi
3
// Định nghĩa cấu trúc của một nút trong cây nhị phân
struct Node {
int data; // giá trị nút chỉ là 1 hoặc 0
struct Node* left;
struct Node* right;
};
A: 0
A: -1
B: 0
B: -1
C: left>right?left:right
C: 1+ (left>right?left:right)
4
Cho hàm sau, đâu là khẳng định đúng
Nút gốc root luôn là A
5
// Hàm kiểm tra xem hai cây nhị phân có đối xứng với nhau hay không (giá
trị tại các nút đối xứng cũng phải bằng nhau)
bool isMirror(struct Node* left, struct Node* right) {
if (A)
return true;
if (B)
return false;
return (C) && isMirror(left->left, right->right) && isMirror(left->right, right->left);
}
// Hàm kiểm tra xem cây nhị phân có đối xứng hay không
bool isSymmetric(struct Node* root) {
if (root == NULL)
return D;
return isMirror(root->left, root->right);
}
A: left == NULL && right == NULL
A: left == NULL || right == NULL
B: left == NULL || right == NULL
B: left == NULL && right == NULL
C: left->data != right->data
C: left->data == right->data
D: true
D: false
6
Cho cây nhị phân tìm tổng quát như hình.
Khi chạy thuật toán ở dưới thì giá trị trả về của hàm sẽ là
7
Cho hàm sau, khi áp dụng với đầu vào là processTree(root->left, root-
>right) thì kết quả trả về sẽ là gì?
root là gốc của cây
processTree(root->left, root->right);
1
2
0
3
Hàm bị lỗi
8
Cho cây nhị phân tìm tổng quát như hình.
Khi chạy thuật toán ở dưới thì
void printLeaves(TN* root)
{
if(NULL==root) return;
queue<pair<TN*, int>> Q;
Q.push(make_pair(root, 0));
int currDepth=0, firstLeafDepth=-1;
while (Q.size() > 0)
{
// lay nut tiep trong hang doi
TN* p = Q.front().first; // la truong thu 1 cuar pair
currDepth = Q.front().second; // la truong thu 2 cua pair
Q.pop();
// meu gap nut la dau tien trong queue --> Khong them tiep cac nut nua
if(p->left==NULL && p->right==NULL)
{
if(firstLeafDepth==-1) firstLeafDepth = currDepth;
if(currDepth==firstLeafDepth)
printf("%c ", p->label);
continue;
}
else if(firstLeafDepth==-1)
{
if (NULL != p->left) Q.push(make_pair(p->left, currDepth + 1));
if (NULL != p->right) Q.push(make_pair(p->right, currDepth + 1));
}
}
printf("\n");
}
9
Cho hàm sau, khi áp dụng với đầu vào là 2 cây trên thì kết quả trả về sẽ là
gì?
0
1
Hàm lỗi
10
Cho cây nhị phân tìm tổng quát như hình.
Khi chạy thuật toán ở dưới thì thứ tự các nút được in ra sẽ là
11
Cho cây nhị phân tìm tổng quát như hình.
Khi chạy thuật toán ở dưới thì giá trị trả về của hàm sẽ là
7
8
9
Không có kết quả nào ở trên là đúng
10
12
Cho đoạn code sau
13
Cho cây nhị phân tìm tổng quát như hình.
Khi chạy thuật toán ở dưới thì giá trị trả về của hàm sẽ là
14
Cho đoạn code sau
15
Cây nhị phân tổng quát chỉ chứa nút trong có 2 con hoặc nút lá
Cho thứ tự duyệt trước A C D F E G J B I K H L M
thứ tự duyệt giữa D C E F G A B J H K L I M
17
Cho cây nhị phân tìm tổng quát như hình.
Khi chạy thuật toán ở dưới thì thứ tự các nút được in ra sẽ là
DEBFHGCA
DBEACFGH
ABDECGFH
Không có thứ tự nào ở trên là đúng
18
Cho cây nhị phân tìm tổng quát như hình.
Khi chạy thuật toán ở dưới thì
calculate(root,1) in ra B C
calculate(root,1) in ra A
calculate(root,2) in ra D E G
Không có kết quả nào ở trên là đúng
calculate(root,2) in ra B C
19
Hàm đếm tần số xuất hiện của khóa k trong cây nhị phân
int countOccurrences(struct Node* root, int k) {
if (root == NULL)
return 0;
int A;
queue<B> Q;
Q.push(root);
struct Node *cur;
while (!Q.empty()) {
C;
Q.pop();
if(cur->data == k) count++;
D Q.push(cur->left);
E Q.push(cur->right);
}
return count;
}
A: count = 0
A: count
B: struct Node
B: struct Node*
C: cur = Q.front()
C: cur = Q.pop()
D:
D: if(cur->left!=NULL)
E: if(cur->left!=NULL)
E: if(cur->right!=NULL)
E:
20
Cho đoạn code sau