#include <iostream>
using namespace std;
// Định nghĩa cấu trúc nút cho cây BST và DLL
class Node {
public:
int val; // Giá trị của nút
Node* left; // Con trỏ trái (trong BST)
Node* right; // Con trỏ phải (trong BST)
Node() : val(0), left(nullptr), right(nullptr) {}
Node(int _val) : val(_val), left(nullptr), right(nullptr) {}
};
class Solution {
private:
Node* prevDLL = nullptr; // Nút trước đó trong quá trình chuyển đổi BST sang DLL
Node* headDLL = nullptr; // Đầu của DLL được tạo từ BST
// Hàm đệ quy để duyệt cây BST theo thứ tự (in-order) và xây dựng DLL
void dfs(Node* root) {
if (root == nullptr) {
return; // Nếu nút hiện tại là null, kết thúc đệ quy
}
dfs(root->left); // Duyệt cây con bên trái
// Xử lý nút hiện tại
if (prevDLL != nullptr) {
prevDLL->right = root; // Liên kết nút trước với nút hiện tại (trong DLL)
root->left = prevDLL; // Liên kết nút hiện tại với nút trước (trong DLL)
} else {
headDLL = root; // Nếu prevDLL là null, nút hiện tại là đầu của DLL
}
prevDLL = root; // Cập nhật nút trước là nút hiện tại
dfs(root->right); // Duyệt cây con bên phải
}
public:
// Hàm chính để chuyển đổi BST thành Doubly Linked List (DLL)
Node* BSTtoDLL(Node* rootBST) {
if (rootBST == nullptr) {
return nullptr; // Nếu BST rỗng, trả về null
}
prevDLL = nullptr;
headDLL = nullptr;
dfs(rootBST); // Gọi hàm dfs để xây dựng DLL
return headDLL; // Trả về đầu của DLL
}
// Hàm để chèn nút vào BST (hàm hỗ trợ)
Node* insert(Node* root, int val) {
if (root == nullptr) {
return new Node(val); // Nếu cây rỗng, tạo nút mới
}
if (val < root->val) {
root->left = insert(root->left, val); // Chèn vào cây con bên trái
} else {
root->right = insert(root->right, val); // Chèn vào cây con bên phải
}
return root; // Trả về gốc của cây
}
// Helper function to print the doubly linked list
void printDLL(Node* head) {
Node* current = head;
while (current != nullptr) {
cout << current->val << " "; // In giá trị của nút hiện tại
current = current->right; // Di chuyển đến nút tiếp theo
}
cout << endl;
}
// Function to print the BST (in-order for verification) - GIỮ NGUYÊN
void printBST(Node* node)
{
if (node == nullptr)
return;
cout << node->val << " ";
printBST(node->left);
printBST(node->right);
}
//============================//
// Chuyển đổi DLL sang BST
private:
Node* sortedDLLToBSTHelper(Node*& headRef, int n) {
if (n <= 0) return nullptr; // Trường hợp cơ sở: không còn nút để xử lý
Node* left = sortedDLLToBSTHelper(headRef, n / 2); // Xây dựng cây con bên trái
Node* root = headRef; // Nút hiện tại trong DLL sẽ là gốc của cây con hiện tại
if (headRef) {
headRef = headRef->right; // Di chuyển con trỏ headRef đến nút tiếp theo trong DLL
}
root->left = left; // Gán cây con bên trái cho nút gốc
root->right = sortedDLLToBSTHelper(headRef, n - n / 2 - 1); // Xây dựng cây con bên phải
return root; // Trả về gốc của cây con hiện tại
}
// Hàm để đếm số lượng nút trong DLL
int countNodesDLL(Node* head) {
int count = 0;
Node* current = head;
while (current != nullptr) {
count++; // Tăng bộ đếm cho mỗi nút
current = current->right; // Di chuyển đến nút tiếp theo
}
return count; // Trả về tổng số nút
}
public:
// Hàm chính để chuyển đổi Doubly Linked List (DLL) thành BST cân bằng
Node* DLLtoBST(Node* head) {
if (!head) return nullptr; // Nếu DLL rỗng, trả về null
int n = countNodesDLL(head); // Đếm số lượng nút trong DLL
Node* currentHead = head; // Tạo một bản sao của head để truyền vào hàm đệ quy
return sortedDLLToBSTHelper(currentHead, n); // Gọi hàm đệ quy để xây dựng BST
}
};
int main() {
Solution sol;
Node* rootBST = nullptr;
rootBST = sol.insert(rootBST, 4);
rootBST = sol.insert(rootBST, 2);
rootBST = sol.insert(rootBST, 5);
rootBST = sol.insert(rootBST, 1);
rootBST = sol.insert(rootBST, 3);
rootBST = sol.insert(rootBST, 6);
rootBST = sol.insert(rootBST, 7);
cout << "BST (Trước): ";
sol.printBST(rootBST);
cout << endl;
Node* headDLL = sol.BSTtoDLL(rootBST);
cout << "Doubly Linked List: ";
sol.printDLL(headDLL);
Node* rootFromDLL = sol.DLLtoBST(headDLL);
cout << "BST (Sau): ";
sol.printBST(rootFromDLL);
cout << endl;
return 0;
}