You are on page 1of 6

Để giải quyết các câu hỏi này, chúng ta cần định nghĩa một cấu trúc dữ liệu để đại

diện cho nút cây nhị


phân tìm kiếm mà mỗi nút là một phân số. Đây là cấu trúc dữ liệu có thể sử dụng:

struct Fraction {

int numerator; // tử số

int denominator; // mẫu số

};

struct TreeNode {

struct Fraction value;

struct TreeNode* left;

struct TreeNode* right;

};

Sau đó, chúng ta có thể sử dụng các hàm sau để giải quyết các câu hỏi:

Câu 1: Liệt kê các phân số đã tối giản

int gcd(int a, int b) {

if (b == 0) {

return a;

return gcd(b, a % b);

int reduceFraction(struct Fraction* f) {

int g = gcd(f->numerator, f->denominator);

f->numerator /= g;

f->denominator /= g;

void listReducedFractions(struct TreeNode* root) {

if (root == NULL) {
return;

listReducedFractions(root->left);

reduceFraction(&(root->value));

printf("%d/%d\n", root->value.numerator, root->value.denominator);

listReducedFractions(root->right);

Hàm gcd là hàm tìm ước chung lớn nhất của hai số nguyên. Hàm reduceFraction là hàm rút gọn phân số.
Hàm listReducedFractions sẽ duyệt cây theo thứ tự trung tố và rút gọn phân số của mỗi nút trước khi in
ra giá trị của nó.

Câu 2: Tìm phân số có tử là số nguyên tố

int isPrime(int n) {

if (n <= 1) {

return 0;

for (int i = 2; i <= sqrt(n); i++) {

if (n % i == 0) {

return 0;

return 1;

void findFractionWithPrimeNumerator(struct TreeNode* root, struct Fraction* result) {

if (root == NULL) {

return;

findFractionWithPrimeNumerator(root->left, result);

if (isPrime(root->value.numerator)) {

*result = root->value;
return;

findFractionWithPrimeNumerator(root->right, result);

Hàm isPrime là hàm kiểm tra một số nguyên có phải là số nguyên tố hay không. Hàm
findFractionWithPrimeNumerator sẽ duyệt cây theo thứ tự trung tố và tìm phân số đầu tiên mà có tử là
số nguyên tố. Nếu tìm thấy, nó sẽ lưu giá trị của phân số đó vào biến result.

Câu 3: Đếm số lượng các nút lá

int countLeaves(struct TreeNode* root) {

if (root == NULL) {

return 0;

if (root->left == NULL && root->right == NULL) {

return 1;

return countLeaves(root->left) + countLeaves(root->right);

Hàm countLeaves sẽ đệ quy đếm số lượng nút lá của cây. Nếu nút hiện tại là nút lá, nó sẽ trả về 1. Nếu
không, nó sẽ đệ quy đếm số lượng nút lá của cây con trái và cây con phải và trả về tổng của hai giá trị đó.

Câu 4: Xóa những phân số có tử là số lẻ

struct TreeNode* deleteNode(struct TreeNode* root, struct Fraction* key) {

if (root == NULL) {

return root;

if (key->numerator < root->value.numerator) {

root->left = deleteNode(root->left, key);

} else if (key->numerator > root->value.numerator) {

root->right = deleteNode(root->right, key);

} else {

if (root->left == NULL) {
struct TreeNode* temp = root->right;

free(root);

return temp;

} else if (root->right == NULL) {

struct TreeNode* temp = root->left;

free(root);

return temp;

struct TreeNode* temp = findMin(root->right);

root->value = temp->value;

root->right = deleteNode(root->right, &(temp->value));

if (root != NULL && root->value.numerator % 2 != 0) {

root = deleteNode(root, &(root->value));

return root;

void deleteFractionsWithOddNumerator(struct TreeNode** root) {

*root = deleteNode(*root, &((struct Fraction) {1, 1}));

Hàm deleteNode là hàm xóa một nút khỏi cây. Hàm findMin là hàm tìm giá trị nhỏ nhất trong cây con
phải của nút hiện tại. Hàm deleteFractionsWithOddNumerator sẽ xóa các nút mà có tử là số lẻ bằng
cách gọi hàm deleteNode với giá trị phân số key được thiết lập là (1, 1) (vì mẫu số luôn là số dương nên
1/1 sẽ không bao giờ xuất hiện trong cây).

Câu 5: Tính tổng các phân số < 3

int isLessThanThree(struct Fraction* f) {

return (double) f->numerator / f->denominator < 3;

void sumFractionsLessThanThree(struct TreeNode* root, double* sum) {

if (root == NULL) {
return;

sumFractionsLessThanThree(root->left, sum);

if (isLessThanThree(&(root->value)))

*sum += (double) root->value.numerator / root->value.denominator;

sumFractionsLessThanThree(root->right, sum);

Hàm `isLessThanThree` sẽ trả về 1 nếu phân số được truyền vào có giá trị nhỏ hơn 3 và trả về 0 nếu
ngược lại. Hàm `sumFractionsLessThanThree` sẽ đệ quy duyệt cây và tính tổng các phân số có giá trị nhỏ
hơn 3. Nếu nút hiện tại có giá trị nhỏ hơn 3, hàm sẽ cộng giá trị phân số của nút đó vào biến tổng.

Câu 6: Tạo cây nhị phân tìm kiếm mới từ các phân số trong cây ban đầu mà có giá trị tử số và mẫu số
đều là số nguyên tố

int isPrime(int n) {

if (n <= 1) {

return 0;

for (int i = 2; i <= sqrt(n); i++) {

if (n % i == 0) {

return 0;

return 1;

struct TreeNode* createNewTree(struct TreeNode* root) {

struct TreeNode* newRoot = NULL;

createNewTreeHelper(root, &newRoot);

return newRoot;
}

void createNewTreeHelper(struct TreeNode* root, struct TreeNode** newRoot) {

if (root == NULL) {

return;

if (isPrime(root->value.numerator) && isPrime(root->value.denominator)) {

*newRoot = insert(*newRoot, root->value);

createNewTreeHelper(root->left, newRoot);

createNewTreeHelper(root->right, newRoot);

Hàm isPrime sẽ kiểm tra xem một số có phải là số nguyên tố hay không. Hàm createNewTree sẽ tạo một
cây nhị phân tìm kiếm mới từ cây ban đầu và trả về nút gốc của cây mới. Hàm createNewTreeHelper sẽ
đệ quy duyệt cây ban đầu và chèn các phân số có giá trị tử số và mẫu số đều là số nguyên tố vào cây mới
bằng cách gọi hàm insert.

You might also like