Download as docx, pdf, or txt
Download as docx, pdf, or txt
You are on page 1of 22

VŨ MINH QUANG – 075205015761

BST
Bài tập thực hành
Hoàn thiện các hàm trong lớp BST
Dưới đây là các hàm cần hoàn thiện cho lớp BST:
1. Duyệt cây theo thứ tự LNR và LRN
2. Tìm kiếm một nút trong cây nhị phân tìm kiếm
3. Xóa một nút trong cây nhị phân tìm kiếm
Hoàn thiện các hàm duyệt cây
void BST::LNR(Node* r) {
if (r != nullptr) {
LNR(r->Getleft());
cout << r->Getkey() << "\n";
LNR(r->Getright());
}
}

void BST::LRN(Node* r) {
if (r != nullptr) {
LRN(r->Getleft());
LRN(r->Getright());
cout << r->Getkey() << "\n";
}
}

void BST::TravelLNR() {
LNR(this->root);
}

void BST::TravelLRN() {
LRN(this->root);
}
Hoàn thiện hàm tìm kiếm
Node* BST::search_x(int k) {
Node* current = this->root;
while (current != nullptr && current->Getkey() != k) {
if (k < current->Getkey())
current = current->Getleft();
else
current = current->Getright();
}
return current;
}
Hoàn thiện hàm xóa nút
void BST::deleteNode(Node* n) {
if (n == nullptr) return;

if (n->Getleft() == nullptr && n->Getright() == nullptr) {


if (n == this->root) {
this->root = nullptr;
} else {
Node* parent = n->Getparent();
if (parent->Getleft() == n) {
parent->Setleft(nullptr);
} else {
parent->Setright(nullptr);
}
}
delete n;
} else if (n->Getleft() == nullptr || n->Getright() == nullptr) {
Node* child = (n->Getleft() != nullptr) ? n->Getleft() : n->Getright();
if (n == this->root) {
this->root = child;
} else {
Node* parent = n->Getparent();
if (parent->Getleft() == n) {
parent->Setleft(child);
} else {
parent->Setright(child);
}
child->Setparent(parent);
}
delete n;
} else {
Node* successor = n->Getright();
while (successor->Getleft() != nullptr) {
successor = successor->Getleft();
}
n->Setkey(successor->Getkey());
deleteNode(successor);
}
}
Áp dụng - Nâng cao
Hàm tính tổng giá trị các nút trên cây
int BST::SumTree(Node* r) {
if (r == nullptr) return 0;
return r->Getkey() + SumTree(r->Getleft()) + SumTree(r->Getright());
}
Hàm tìm giá trị nguyên lớn nhất và nhỏ nhất
int BST::FindMax(Node* r) {
while (r->Getright() != nullptr) {
r = r->Getright();
}
return r->Getkey();
}

int BST::FindMin(Node* r) {
while (r->Getleft() != nullptr) {
r = r->Getleft();
}
return r->Getkey();
}
Hàm đếm số lượng các nút
int BST::CountNodes(Node* r) {
if (r == nullptr) return 0;
return 1 + CountNodes(r->Getleft()) + CountNodes(r->Getright());
}
Hàm đếm số lượng các nút lá
int BST::CountLeaves(Node* r) {
if (r == nullptr) return 0;
if (r->Getleft() == nullptr && r->Getright() == nullptr) return 1;
return CountLeaves(r->Getleft()) + CountLeaves(r->Getright());
}
Hàm tính chiều cao của cây
int BST::Height(Node* r) {
if (r == nullptr) return 0;
return 1 + max(Height(r->Getleft()), Height(r->Getright()));
}
Hàm tính tổng các Node trên một tầng
int BST::SumLevel(Node* r, int level) {
if (r == nullptr) return 0;
if (level == 0) return r->Getkey();
return SumLevel(r->Getleft(), level - 1) + SumLevel(r->Getright(), level - 1);
}
Hàm đếm số lượng số nguyên tố trên cây
bool isPrime(int n) {
if (n <= 1) return false;
for (int i = 2; i * i <= n; i++) {
if (n % i == 0) return false;
}
return true;
}

int BST::CountPrimes(Node* r) {
if (r == nullptr) return 0;
return isPrime(r->Getkey()) + CountPrimes(r->Getleft()) + CountPrimes(r-
>Getright());
}
Sử dụng cây nhị phân tìm kiếm để giải bài toán đếm giá trị phân biệt
#include <set>

int countDistinct(vector<int>& arr) {


set<int> distinct_elements;
for (int num : arr) {
distinct_elements.insert(num);
}
return distinct_elements.size();
}
Hàm main hoàn chỉnh
int main() {
BST *tree = new BST();
Node *n;
n = new Node(10);
tree->InsertNode(n);
n = new Node(19);
tree->InsertNode(n);
n = new Node(9);
tree->InsertNode(n);
n = new Node(3);
tree->InsertNode(n);
n = new Node(19);
tree->InsertNode(n);
n = new Node(8);
tree->InsertNode(n);
n = new Node(4);
tree->InsertNode(n);
n = new Node(1);
tree->InsertNode(n);
n = new Node(15);
tree->InsertNode(n);

cout << "Duyet theo thu tu NLR:\n";


tree->TravelNLR();

cout << "Duyet theo thu tu LNR:\n";


tree->TravelLNR();

cout << "Duyet theo thu tu LRN:\n";


tree->TravelLRN();

int sum = tree->SumTree(tree->Getroot());


cout << "Tong gia tri cac nut tren cay: " << sum << endl;

int maxVal = tree->FindMax(tree->Getroot());


int minVal = tree->FindMin(tree->Getroot());
cout << "Gia tri lon nhat: " << maxVal << endl;
cout << "Gia tri nho nhat: " << minVal << endl;

int nodeCount = tree->CountNodes(tree->Getroot());


cout << "So luong cac nut tren cay: " << nodeCount << endl;
int leafCount = tree->CountLeaves(tree->Getroot());
cout << "So luong cac nut la tren cay: " << leafCount << endl;

int height = tree->Height(tree->Getroot());


cout << "Chieu cao cua cay: " << height << endl;

int level = 2; // Ví dụ tính tổng các node ở tầng 2


int sumLevel = tree->SumLevel(tree->Getroot(), level);
cout << "Tong gia tri cac nut o tang " << level << ": " << sumLevel << endl;

int primeCount = tree->CountPrimes(tree->Getroot());


cout << "So luong so nguyen to tren cay: " << primeCount << endl;

// Ví dụ đếm giá trị phân biệt trong dãy số


vector<int> arr = {10, 19, 9, 3, 19, 8, 4, 1, 15};
int distinctCount = countDistinct(arr);
cout << "So luong gia tri phan biet trong day so: " << distinctCount << endl;

return 0;
}
BÀI TẬP ỨNG DỤNG
Bài 1:
Định nghĩa lớp Node

#ifndef NODE_H
#define NODE_H
class Node {
public:
Node();
Node(char k);
virtual ~Node();

Node* Getleft() { return left; }


void Setleft(Node* val) { left = val; }
Node* Getright() { return right; }
void Setright(Node* val) { right = val; }
char Getkey() { return key; }
void Setkey(char val) { key = val; }
int Getcount() { return count; }
void Setcount(int val) { count = val; }

protected:

private:
Node* left;
Node* right;
char key;
int count;
};

#endif // NODE_H

Node::Node() {
this->key = '\0';
this->left = nullptr;
this->right = nullptr;
this->count = 0;
}

Node::Node(char k) {
this->key = k;
this->left = nullptr;
this->right = nullptr;
this->count = 1;
}

Node::~Node() {}
Định nghĩa lớp BST

#ifndef BST_H
#define BST_H
#include "Node.h"
#include <iostream>

class BST {
public:
BST();
virtual ~BST();

Node* Getroot() { return root; }


void Setroot(Node* val) { root = val; }
bool InsertNode(char k);
Node* search_x(char k);
int countCharacter(char k);

protected:

private:
Node* root;
bool InsertNode(Node* root, char k);
};

#endif // BST_H

BST::BST() {
this->root = nullptr;
}

BST::~BST() {}

bool BST::InsertNode(Node* root, char k) {


if (root == nullptr) {
this->root = new Node(k);
return true;
}
if (root->Getkey() == k) {
root->Setcount(root->Getcount() + 1);
return true;
} else if (root->Getkey() > k) {
if (root->Getleft() == nullptr) {
root->Setleft(new Node(k));
} else {
return InsertNode(root->Getleft(), k);
}
} else {
if (root->Getright() == nullptr) {
root->Setright(new Node(k));
} else {
return InsertNode(root->Getright(), k);
}
}
return true;
}

bool BST::InsertNode(char k) {
return InsertNode(this->root, k);
}

Node* BST::search_x(char k) {
Node* current = this->root;
while (current != nullptr && current->Getkey() != k) {
if (k < current->Getkey())
current = current->Getleft();
else
current = current->Getright();
}
return current;
}

int BST::countCharacter(char k) {
Node* node = search_x(k);
if (node != nullptr) {
return node->Getcount();
}
return 0;
}
Đọc văn bản và xây dựng cây BST

#include "BST.h"
#include <iostream>
#include <string>

using namespace std;

void buildTreeFromText(BST& tree, const string& text) {


for (char c : text) {
if (isalpha(c)) {
tree.InsertNode(tolower(c));
}
}
}

int main() {
BST tree;
string text = "Day la mot van ban khong dau de thu nghiem. Mot van ban
khong dau khac.";

buildTreeFromText(tree, text);

char ch;
cout << "Nhap vao ky tu can kiem tra: ";
cin >> ch;
ch = tolower(ch);

int count = tree.countCharacter(ch);


if (count > 0) {
cout << "Ky tu '" << ch << "' xuat hien " << count << " lan trong van ban."
<< endl;
} else {
cout << "Ky tu '" << ch << "' khong xuat hien trong van ban." << endl;
}

return 0;
}

Giải thích

1. Lớp Node: Lưu trữ ký tự và số lần xuất hiện của nó, cùng với con trỏ tới các nút con
trái và phải.
2. Lớp BST: Cung cấp các phương thức để chèn ký tự, tìm kiếm và đếm số lần xuất hiện
của ký tự trong cây.
3. Hàm buildTreeFromText: Đọc từng ký tự trong văn bản, nếu ký tự là chữ cái thì
chuyển nó thành chữ thường và chèn vào cây.
4. Hàm countCharacter: Tìm kiếm ký tự trong cây và trả về số lần xuất hiện của nó.

Chương trình sẽ yêu cầu người dùng nhập vào một ký tự và sau đó kiểm tra số lần xuất hiện
của ký tự đó trong văn bản đã cho.

Bài 2:
Định nghĩa lớp Node để lưu trữ từ và số lần xuất hiện của nó

#ifndef NODE_H
#define NODE_H

#include <string>

class Node {
public:
Node();
Node(std::string k);
virtual ~Node();

Node* Getleft() { return left; }


void Setleft(Node* val) { left = val; }
Node* Getright() { return right; }
void Setright(Node* val) { right = val; }
std::string Getkey() { return key; }
void Setkey(std::string val) { key = val; }
int Getcount() { return count; }
void Setcount(int val) { count = val; }

protected:

private:
Node* left;
Node* right;
std::string key;
int count;
};

#endif // NODE_H

#include "Node.h"

Node::Node() {
this->key = "";
this->left = nullptr;
this->right = nullptr;
this->count = 0;
}

Node::Node(std::string k) {
this->key = k;
this->left = nullptr;
this->right = nullptr;
this->count = 1;
}

Node::~Node() {}
Định nghĩa lớp BST để quản lý các nút và thực hiện các thao tác chèn, tìm kiếm và thống kê

#ifndef BST_H
#define BST_H
#include "Node.h"
#include <iostream>
class BST {
public:
BST();
virtual ~BST();

Node* Getroot() { return root; }


void Setroot(Node* val) { root = val; }
bool InsertNode(std::string k);
Node* search_x(std::string k);
int countWord(std::string k);
void printTree(Node* root);
void printTree();

protected:

private:
Node* root;
bool InsertNode(Node* root, std::string k);
};

#endif // BST_H

#include "BST.h"

BST::BST() {
this->root = nullptr;
}

BST::~BST() {}

bool BST::InsertNode(Node* root, std::string k) {


if (root == nullptr) {
this->root = new Node(k);
return true;
}
if (root->Getkey() == k) {
root->Setcount(root->Getcount() + 1);
return true;
} else if (root->Getkey() > k) {
if (root->Getleft() == nullptr) {
root->Setleft(new Node(k));
} else {
return InsertNode(root->Getleft(), k);
}
} else {
if (root->Getright() == nullptr) {
root->Setright(new Node(k));
} else {
return InsertNode(root->Getright(), k);
}
}
return true;
}
bool BST::InsertNode(std::string k) {
return InsertNode(this->root, k);
}

Node* BST::search_x(std::string k) {
Node* current = this->root;
while (current != nullptr && current->Getkey() != k) {
if (k < current->Getkey())
current = current->Getleft();
else
current = current->Getright();
}
return current;
}

int BST::countWord(std::string k) {
Node* node = search_x(k);
if (node != nullptr) {
return node->Getcount();
}
return 0;
}

void BST::printTree(Node* root) {


if (root != nullptr) {
printTree(root->Getleft());
std::cout << root->Getkey() << ": " << root->Getcount() << std::endl;
printTree(root->Getright());
}
}

void BST::printTree() {
printTree(this->root);
}
Đọc văn bản và xây dựng cây BST từ các từ trong văn bản

#include "BST.h"
#include <iostream>
#include <string>
#include <sstream>
#include <algorithm>

using namespace std;

void buildTreeFromText(BST& tree, const string& text) {


stringstream ss(text);
string word;
while (ss >> word) {
tree.InsertNode(word);
}
}

int main() {
BST tree;
string text = "hoc sinh di hoc mon sinh hoc";
buildTreeFromText(tree, text);

char ch;
string word;
cout << "Nhap vao tu can kiem tra: ";
cin >> word;

int count = tree.countWord(word);


if (count > 0) {
cout << "Tu '" << word << "' xuat hien " << count << " lan trong van ban."
<< endl;
} else {
cout << "Tu '" << word << "' khong xuat hien trong van ban." << endl;
}

cout << "\nCay BST chua thong ke cac tu trong van ban:\n";
tree.printTree();

return 0;
}

Giải thích

1. Lớp Node: Lưu trữ từ và số lần xuất hiện của nó, cùng với con trỏ tới các nút con trái
và phải.
2. Lớp BST: Cung cấp các phương thức để chèn từ, tìm kiếm và đếm số lần xuất hiện
của từ trong cây, và in cây BST.
3. Hàm buildTreeFromText: Đọc từng từ trong văn bản, chuyển nó thành chữ thường
và chèn vào cây.
4. Hàm countWord: Tìm kiếm từ trong cây và trả về số lần xuất hiện của nó.
5. Hàm printTree: In ra cây BST theo thứ tự in-order để dễ nhìn.

You might also like