✨Cây tìm kiếm nhị phân

Cây tìm kiếm nhị phân

Cây tìm kiếm nhị phân (viết tắt tiếng Anh: BST - Binary Search Tree) là một cấu trúc dữ liệu rất thuận lợi cho bài toán tìm kiếm. Mỗi cây tìm kiếm nhị phân đều có tính chất sau: Với mỗi nút x, các nút ở cây con bên trái của x đều có giá trị key nhỏ hơn x: y.key\leq x.key, còn các nút ở cây con bên phải của x đều có key lớn hơn hoặc bằng x: y.key\geq x.key.

Định nghĩa

trái|Cây tìm kiếm nhị phân Cây tìm kiếm ứng với n khóa k_1,k_2,...k_n là cây nhị phân mà mỗi nút đều được gán một khóa sao cho với mỗi mỗi nút k:

  • Mọi khóa trên cây con trái đều nhỏ hơn khóa trên nút k
  • Mọi khóa trên cây con phải đều lớn hơn khóa trên nút k

Cây tìm kiếm nhị phân là một cấu trúc dữ liệu cơ bản được sử dụng để xây dựng các cấu trúc dữ liệu trừu tượng hơn như các tập hợp, đa tập hợp, các dãy kết hợp.

Nếu một BST có chứa các giá trị giống nhau thì nó biểu diễn một đa tập hợp. Cây loại này sử dụng các bất đẳng thức không nghiêm ngặt. Mọi nút trong cây con trái có khóa nhỏ hơn khóa của nút cha, mọi nút trên cây con phải có nút lớn hơn hoặc bằng khóa của nút cha.

Nếu một BST không chứa các giá trị giống nhau thì nó biểu diễn một tập hợp đơn trị như trong lý thuyết tập hợp. Cây loại này sử dụng các bất đẳng thức nghiêm ngặt. Mọi nút trong cây con trái có khóa nhỏ hơn khóa của nút cha, mọi nút trên cây con phải có khóa lớn hơn khóa của nút cha.

Việc chọn đưa các giá trị bằng nhau vào cây con phải (hay trái) là tùy theo mỗi người. Một số người cũng đưa các giá trị bằng nhau vào cả hai phía, nhưng khi đó việc tìm kiếm trở nên phức tạp hơn.

Các phép toán trên BST

Tìm kiếm (Searching)

Việc tìm một khóa trên BST có thể thực hiện nhờ đệ quy. Chúng ta bắt đầu từ gốc. Nếu khóa cần tìm bằng khóa của gốc thì khóa đó trên cây, nếu khóa cần tìm nhỏ hơn khóa ở gốc, ta phải tìm nó trên cây con trái, nếu khóa cần tìm lớn hơn khóa ở gốc, ta phải tìm nó trên cây con phải. Nếu cây con (trái hoặc phải) là rỗng thì khóa cần tìm không có trên cây.

Tập tin:bstreesearchexample.jpg

Giả mã Search_binary_tree(node, key); if node is Null then return None; / key not found /

   **if** key < node.key:
       **return** search binary_tree(node.left, key);
   **else**  
       if key > node.key
           **return** search_binary_tree(node.right, key)
       **else**  /* key is equal to node key */
           **return** node.value;  # found key

Mã Python:

def search_binary_tree(node, key): if node is None: return None # key not found if key < node.key: return search_binary_tree(node.leftChild, key) elif key > node.key: return search_binary_tree(node.rightChild, key) else: # key is equal to node key return node.value # found key

Thời gian tìm kiếm trung bình là O(log 2n), và là O(n) khi cây là không cân bằng chỉ là một danh sách liên kết.

Chèn (Insertion)

Phép chèn bắt đầu giống như phép tìm kiếm; Nếu khóa của gốc khác khóa cần chèn ta tìm nó trong cây con trái hoặc phải. Nếu cây con trái hoặc phải tương ứng là rỗng (không tìm thấy) thì thêm một nút và gán cho nút ấy khóa cần chèn.

Sau đây là mã trong C++: void InsertNode(struct node &treeNode, struct node newNode) { //Inserts node pointered by "newNode" to the subtree started by "treeNode" if (treeNode == NULL) treeNode = newNode; //Only changes "node" when it is NULL else if (newNode->value < treeNode->value) InsertNode(treeNode->left, newNode); else InsertNode(treeNode->right, newNode); }

Mã Python: def binary_tree_insert(node, key, value): if node is None: return TreeNode(None, key, value, None)

 if key == node.key:
     return TreeNode(node.left, key, value, node.right)
 if key < node.key:
     return TreeNode(binary_tree_insert(node.left, key, value), node.key, node.value, node.right)
 else:
     return TreeNode(node.left, node.key, node.value, binary_tree_insert(node.right, key, value))

Xóa (Deletion)

Xét các trường hợp sau

  • Xóa một lá: Vì lá không có con nên chỉ cần giải phóng nó khỏi cây.

Tập tin:Bstreedeleteleafexample.jpg

  • Xóa nút có một con: Xóa và thay thế nó bằng con duy nhất của nó.

Tập tin:Bstreedeleteonechildexample.jpg

  • Xóa một nút có hai con: Xóa nút đó và thay thế nó bằng nút có khóa lớn nhất trong các khóa nhỏ hơn khóa của nó (được gọi là "nút tiền nhiệm" -nút cực phải của cây con trái) hoặc nút có khóa nhỏ nhất trong các khóa lớn hơn nó (được gọi là "nút kế vị" - nút cực trái của cây con phải) Cũng có thể tìm nút tiền nhiệm hoặc nút kế vị đổi chỗ nó với nút cần xóa và sau đó xóa nó. Vì các nút kiểu này có ít hơn hai con nên việc xóa nó được quy về hai trường hợp trước.

Tập tin:Bstreedeletenotrightchildexample.jpg

Sau đây là mã C++

void DeleteNode(struct node*& node) { if (node->left == NULL) {

     struct node* temp = node;
     node = node->right;
     delete temp;
 } **else if** (node->right == **NULL**) {

     struct node* temp = node;
     node = node->left;
     delete temp;

 } **else** {
     _// In-Order predecessor(right most child of left subtree)_ 
     _// Node has two children - get max of left subtree_

     struct node** temp = &(node->left); // get left node of the original node

     _// find the right most child of the subtree of the left node_
     **while** ((*temp)->right != **NULL**) {
         temp = &((*temp)->right);
     }

     _// copy the value from the right most child of left subtree to the original node_
     node->value = (*temp)->value;

     _// then delete the right most child of left subtree since it's value is_
     _// now in the original node_
     DeleteNode(*temp);
 }

}

Mã python: def findMin(self): ''' Finds the smallest element that is a child of self ''' current_node = self while current_node.left_child: current_node = current_node.left_child return current_node

def replace_node_in_parent(self, new_value=None): ''' Removes the reference to self from self.parent and replaces it with new_value. ''' if self == self.parent.left_child: self.parent.left_child = new_value else: self.parent.right_child = new_value if new_value: new_value.parent = self.parent

def binary_tree_delete(self, key): if key < self.key: self.left_child.binary_tree_delete(key) elif key > self.key: self.right_child.binary_tree_delete(key) else: # delete the key here if self.left_child and self.right_child: # if both children are present

get the smallest node that's bigger than self

        successor = self.right_child.findMin()
        self.key = successor.key
        # if *successor* has a child, replace it with that
        # at this point, it can only have a *right_child*
        # if it has no children, *right_child* will be "None"
        successor.replace_node_in_parent(successor.right_child)
    elif self.left_child or self.right_child:   # if the node has only one child
        if self.left_child:
            self.replace_node_in_parent(self.left_child)
        else:
            self.replace_node_in_parent(self.right_child)
    else: # this node has no children
        self.replace_node_in_parent(None)

Phép duyệt

Khi một cây tìm kiếm nhị phân được tạo ra, tất cả các nút có thể được duyệt theo thứ tự giữa nhờ duyệt đệ quy cây con bên trái, in nút đang duyệt, rồi duyệt đệ quy cây con bên phải, tiếp tục làm như vây với mỗi nút của cây trong quá trình đệ quy. Với mọi cây nhị phân, cây có thể được duyệt theo thứ tự trước() hoặc theo thứ tự sau(), cả hai cách đều hữu dụng với cây tìm kiếm nhị phân.

Đoạn mã cho duyệt theo thứ giữa được viết dưới đây với C++: void traverse_binary_tree(struct node* n) { if(n==null) //Cay rong return NULL; else { traverse_binary_tree(n->left); //Duyet cay con trai theo thu tu giua printf("%d",n.key); //Tham nut traverse_binary_tree(n->right); //Duyet cay con phai theo thu tu giua } }

Phép duyệt có độ phức tạp tính toán là Ω(n), vì nó phải duyệt qua tất cả các nút. Độ phức tạp trên cũng là O("n").

Sắp xếp

Một cây tìm kiếm nhị phân có thể được sử dụng như một giải thuật sắp xếp đơn giản nhưng hiểu quả. Giống như heapsort, chúng ta chèn tất cả các giá trị chúng ta muốn sắp xếp vào một cây tìm kiếm nhị phân và in ra kết quả theo thứ tự: def build_binary_tree(values): tree = None for v in values: tree = binary_tree_insert(tree, v) return tree

def get_inorder_traversal(root): ''' Returns a list containing all the values in the tree, starting at root. Traverses the tree in-order(leftChild, root, rightChild). ''' result = [] traverse_binary_tree(root, lambda element: result.append(element)) return result

Trường hợp xấu nhất của build_binary_tree có độ phức tạp là \Theta(n^2)—nếu nhập vào một dãy giá trị đã sắp xếp, cây nhị phân tạo thành sẽ không có các nút trái. Ví dụ, traverse_binary_tree([1, 2, 3, 4, 5]) tạo thành cây (1 (2 (3 (4 (5))))).

Có một vài cách để vượt qua trường hợp này với các cây nhị phân đơn giản; cách đơn giản nhất là cây tìm kiếm nhị phân tự cân bằng. Với thủ tục này được sử dụng với cây nhị phân tự cân bằng, trường hợp xấu nhất sẽ có độ phức tạp là O(_n_log n).

Mã giả bằng ngôn ngữ C

#include #include #include //Khai bao cay nhi phan typedef char TData; typedef struct TNode{ TData Data; TNode* left; TNode* right; }; typedef TNode* TTree; /*=== Tao cay rong ===*/ void MakeNull_Tree(TTree *T) { (*T)=NULL; } /*=== Kiem tra cay rong ===*/ int EmptyTree(TTree T) { return T==NULL; } /*=== Xac dinh con trai ===*/ TTree LeftChild(TTree T) { if(T != NULL) return T->left; else return NULL; } /*=== Xac dinh con phai ===*/ TTree RightChild(TTree T) { if(T != NULL) return T->right; else return NULL; } /*=== Xac dinh nut la ===*/ int isLeaf(TTree T) { if((T != NULL) && (T->left == NULL) && (T->right == NULL)) return 1; else return NULL; } /*=== Xac dinh so nut cua cay ===*/ int nb_nodes(TTree T) { if(EmptyTree(T)) return 0; else return nb_nodes(T->left)+nb_nodes(T->right)+1; }

// Ham xac dinh gia tri lon nhat trong hai so nguyen

int max(int value1,int value2) { return ((value1 > value2) ? value1: value2); //xac dinh gia tri lon nhat trong 2 gia tri so nguyen }

// Ham xac dinh chieu cao cua cay

int TreeHeight(TTree T) { int height=0; if (!EmptyTree(T)) { if (isLeaf(T)) return 0; else height = max(TreeHeight(LeftChild(T)),TreeHeight(RightChild(T)))+1; } return height; }

// Ham xac dinh so nut la tren cay

int nb_leaf(TTree T) { int leaf=0; if(!EmptyTree(T)) { if (isLeaf(T)) leaf++; else leaf = nb_leaf(LeftChild(T))+nb_leaf(RightChild(T)); }; return leaf; }

/=== Tao cay moi tu hai cay co san ===/ TTree Create2(TData v,TTree left,TTree right) { TTree N; // Khai bao 1 cay moi N = (TNode)malloc(sizeof(TNode)); //Cap phat vung nho cho nut N N->Data = v; // Nhan cua nut N la v N->left = left; //Con trai cua N la cay left N->right = right; //Con phai cua N la cay right return N; } /=== Duyet cay nhi phan ===*/ //Duyet tien tu void NLR(TTree T) { if(!EmptyTree(T)) { printf(" %c",T->Data); //Xu ly nut NLR(LeftChild(T)); //Duyet tien tu con trai NLR(RightChild(T)); //Duyet tien tu con phai } } //Duyet trung tu void LNR(TTree T) { if(!EmptyTree(T)) { LNR(LeftChild(T)); //Duyet trung tu con trai printf(" %c",T->Data);//Xu ly nut LNR(RightChild(T));//Duyet trung tu con phai } } //Duyet hau tu void LRN(TTree T) { if(!EmptyTree(T)) { LRN(LeftChild(T)); //Duyet hau tu con trai LRN(RightChild(T));//Duyet hau tu con phai printf(" %c",T->Data);//Xu ly nut } }

Các loại cây tìm kiếm nhị phân

Có rất nhiều loại cây tìm kiếm nhị phân. cây AVL và cây đỏ đen đều là các dạng của cây tìm kiếm nhị phân tự cân bằng. () là một cây nhị phân có thể tự đẩy các phần mới vào gần nút gốc. Trong một treap ("cây heap"), mỗi nút có một sự ưu tiên (priority) và các nút cha có sự ưu tiên cao hơn các nút con của chúng.

👁️ 0 | 🔗 | 💖 | ✨ | 🌍 | ⌚
**Cây tìm kiếm nhị phân** (viết tắt tiếng Anh: BST - _Binary Search Tree_) là một cấu trúc dữ liệu rất thuận lợi cho bài toán tìm kiếm. Mỗi cây tìm kiếm nhị phân đều
Trong khoa học máy tính, **tìm kiếm nhị phân** (), còn gọi là **tìm kiếm nửa khoảng** (_half-interval search_), **tìm kiếm logarit** (_logarithmic search_), hay **chặt nhị phân** (_binary chop_), là một thuật toán tìm
Trong khoa học máy tính, **Phép quay** trên các cây nhị phân là một phép biến đổi làm thay đổi vai trò cha con giữa 2 nút trên cây. Có hai phép quay là quay
Trong ngành khoa học máy tính, một **giải thuật tìm kiếm** là một thuật toán lấy đầu vào là một bài toán và trả về kết quả là một lời giải cho bài toán đó,
thumbnail|right|upright=1.35|Đồ thị của dưới dạng là hàm của một số thực dương Trong toán học, **logarit nhị phân** () là lũy thừa mà số cần phải được nâng lên để được số , nghĩa là
**Cây splay** là một cây tìm kiếm nhị phân tự cân bằng. Nó có thực hiện các thao tác cơ bản như chèn, tìm, và xóa trong thời gian trừ dần O(log n). Với nhiều
**Cây đỏ đen** (tiếng Anh: _red-black tree_) là một dạng cây tìm kiếm nhị phân tự cân bằng, một cấu trúc dữ liệu được sử dụng trong khoa học máy tính. Cấu trúc ban đầu
Trong khoa học máy tính, một **Cây AVL** là một cây tìm kiếm nhị phân tự cân bằng, và là cấu trúc dữ liệu đầu tiên có khả năng này. Trong một cây AVL, tại
phải|khung|Một cây có dán nhãn với 6 đỉnh và 5 cạnh **Cây** là khái niệm quan trọng trong lý thuyết đồ thị, cấu trúc dữ liệu và giải thuật. Cây là một đồ thị mà
nhỏ|Ví dụ về một cây nhị phân Trong khoa học máy tính, **cây** là một cấu trúc dữ liệu được sử dụng rộng rãi gồm một tập hợp các nút (tiếng Anh: _node_) được liên
Trong khoa học máy tính, **cây 2-3-4** là cây nhiều nhánh mà mỗi nút của nó có thể có đến bốn nút con và ba mục dữ liệu. Cây 2-3-4 là cây cân bằng giống
thumb|Một cây nhị phân được gắn nhãn có kích thước là 9 và chiều cao là 3, với nút gốc có giá trị là 2. Cây trên không cân bằng và không được sắp xếp.
Trong khoa học máy tính, **treap** và **cây tìm kiếm nhị phân ngẫu nhiên hóa** là hai dạng cấu trúc dữ liệu cây tìm kiếm nhị phân liên quan chặt chẽ đến nhau. Chúng lưu
Trong phát sinh chủng loại học, **khóa** **lưỡng phân** (tiếng Anh: **single-access key**, **dichotomous key**, **sequential key**, **analytical key**, **pathway key**) là khóa nhận dạng (_Identification key_) trong đó trình tự và cấu trúc của
Trong khoa học máy tính, **B-cây** là một cấu trúc dữ liệu dạng cây cho phép tìm kiếm, truy cập tuần tự, chèn, xóa trong thời gian lôgarit. B-cây là một tổng quát hóa của
Một **đống nhị phân** là một cấu trúc dữ liệu đống dựa trên cây nhị phân. Đống nhị phân thường được sử dụng để triển khai hàng đợi ưu tiên. Đống nhị phân được giới
nhỏ|315x315px|Một danh bạ điện thoại nhỏ được xem như một bảng băm. Trong khoa học máy tính, **bảng băm** là một cấu trúc dữ liệu sử dụng hàm băm để ánh xạ từ giá trị
**_Thư kiếm ân cừu lục_** (書劍恩仇錄) là một tiểu thuyết võ hiệp của nhà văn Kim Dung, được đăng trên _Tân vãn báo_ của Hồng Kông từ ngày 8 tháng 2 năm 1955 đến ngày
Đây là danh sách các cấu trúc dữ liệu. Bạn có thể xem danh sách thuật ngữ rộng hơn tại danh sách các thuật ngữ liên quan đến cấu trúc dữ liệu và giải thuật.
Mô tảHàng mới 100% và chất lượng caoMàu sắc: Như hình ảnh hiển thịDOPPLER thai nhi bỏ túi là một thiết bị sản khoa cầm tay, áp dụng cho bệnh viện, phòng khám và nhà
**Trèo cây** là tên gọi chung của một nhóm các loài chim dạng sẻ nhỏ thuộc chi **_Sitta_** trong họ **Sittidae**, có hình thái đặc trưng là đầu to, đuôi ngắn, mỏ và bàn chân
phải|Cây hậu tố cho xâu BANANA. Mỗi xâu con được kết thúc bởi ký tự đặc biệt $. Sáu đường từ gốc đến lá (ký hiệu bởi ô vuông) tương ứng với sáu hậu tố
Thông tin sản phẩm Chế độ sản phẩm: FD-270B Đầu dò tần số:2. 0 MHz Tỷ lệ phạm vi hiển thị:50-230Bpm Phạm vi lỗi:± 2bpm Ngày Hiệu Quả:5 năm Kích thước:14 Cm(L) * 10.5 Cm(W)
Thông tin sản phẩm Chế độ sản phẩm: FD-270G Đầu dò tần số:2. 0 MHz Tỷ lệ phạm vi hiển thị:50-230Bpm Phạm vi lỗi:± 2bpm Ngày Hiệu Quả:5 năm Kích thước:14Cm(L) * 10.5Cm(W) * 3Cm(H)
Thông tin sản phẩm Chế độ sản phẩm: FD-270B Đầu dò tần số:2. 0 MHz Tỷ lệ phạm vi hiển thị:50-230Bpm Phạm vi lỗi:± 1bpm Ngày Hiệu Quả:5 năm Kích cỡ:14Cm(L) * 10.5Cm(W) * 3Cm(H)
Thông tin sản phẩm Chế độ sản phẩm: FD-270B Đầu dò tần số:2. 0 MHz Tỷ lệ phạm vi hiển thị:50-230Bpm Phạm vi lỗi:± 2bpm Ngày Hiệu Quả:5 năm Kích thước:14 Cm(L) * 10.5 Cm(W)
Thông tin sản phẩm Chế độ sản phẩm: FD-270B Đầu dò tần số:2. 0 MHz Tỷ lệ phạm vi hiển thị:50-230Bpm Phạm vi lỗi:± 1bpm Ngày Hiệu Quả:5 năm Kích cỡ:14Cm(L) * 10.5Cm(W) * 3Cm(H)
Thông tin sản phẩm Chế độ sản phẩm: FD-270C Đầu dò tần số:2. 0 MHz Tỷ lệ phạm vi hiển thị:50-230Bpm Phạm vi lỗi:± 2bpm Ngày Hiệu Quả:5 năm Kích thước:14 Cm(L) * 10.5 Cm(W)
Thông tin sản phẩm Chế độ sản phẩm: FD-270B Đầu dò tần số:2. 0 MHz Tỷ lệ phạm vi hiển thị:50-230Bpm Phạm vi lỗi:± 1bpm Ngày Hiệu Quả:5 năm Kích cỡ:14Cm(L) * 10.5Cm(W) * 3Cm(H)
nhỏ| Một sơ đồ cho thấy cách người dùng tương tác với [[phần mềm ứng dụng trên một máy tính để bàn thông thường. Lớp phần mềm ứng dụng giao tiếp với hệ điều hành,
**Động đất Thổ Nhĩ Kỳ – Syria 2023**, hay **Trận động đất ở Thổ Nhĩ Kỳ và Syria** (theo cách gọi của báo chí), là hai trận động đất xảy ra ở miền nam và
Phần mềm là các lệnh được lập trình mà được lưu trữ trong bộ nhớ được lưu trữ của các máy tính kỹ thuật số để bộ xử lý thực hiện. Phần mềm là một
**Đại chiến Thổ Nhĩ Kỳ** (Tiếng Đức: _Großer Türkenkrieg_), còn được gọi là **Chiến tranh Liên đoàn Thần thánh** (Tiếng Thổ Nhĩ Kỳ: _Kutsal İttifak Savaşları_), là một loạt các cuộc xung đột giữa Đế
Bánh gạo mầm tím than là một lựa chọn dinh dưỡng tuyệt vời cho những ai đang tìm kiếm một loại thực phẩm vừa ngon miệng vừa có lợi cho sức khỏe.Bánh gạo mầm tím
Bánh gạo mầm tím than là một lựa chọn dinh dưỡng tuyệt vời cho những ai đang tìm kiếm một loại thực phẩm vừa ngon miệng vừa có lợi cho sức khỏe.Bánh gạo mầm tím
Thổ Nhĩ Kỳ là thành viên sáng lập của OECD và G20, đồng thời được xếp vào nhóm các quốc gia E7 , EAGLEs và NIC. Tính đến năm 2023, nền kinh tế Thổ Nhĩ
Một **bản phân phối ****Linux** (thường được gọi tắt là **distro**) là một hệ điều hành được tạo dựng từ tập hợp nhiều phần mềm dựa trên hạt nhân Linux và thường có một hệ
thumb|alt=Màn hình máy tính của hệ điều hành, màn hình hiển thị các ứng dụng phần mềm tự do khác nhau.|Ví dụ về một hệ điều hành phần mềm tự do hiện đại chạy một
Cam két của Chất QuêDầu dừa nấu thủ công nguyên chất 100%, không pha chế tạp chất, hóa chất.Đây là loại dầu dừa nguyên chất ép lạnh không mùi dùng để massage cơ thể hoặc
Cam két của Chất Quê Dầu dừa nấu thủ công nguyên chất 100%, không pha chế tạp chất, hóa chất. Đây là loại dầu dừa nguyên chất ép lạnh không mùi dùng để massage cơ
Cam két của Chất Quê Dầu dừa nấu thủ công nguyên chất 100%, không pha chế tạp chất, hóa chất. Đây là loại dầu dừa nguyên chất ép lạnh không mùi dùng để massage cơ
Cam két của Chất Quê Dầu dừa nấu thủ công nguyên chất 100%, không pha chế tạp chất, hóa chất. Đây là loại dầu dừa nguyên chất ép lạnh không mùi dùng để massage cơ
Cam két của Chất QuêDầu dừa nấu thủ công nguyên chất 100%, không pha chế tạp chất, hóa chất.Đây là loại dầu dừa nguyên chất ép lạnh không mùi dùng để massage cơ thể hoặc
Cam két của Chất Quê Dầu dừa nấu thủ công nguyên chất 100%, không pha chế tạp chất, hóa chất. Đây là loại dầu dừa nguyên chất ép lạnh không mùi dùng để massage cơ
Bài viết này là **danh sách các thuật toán** cùng một mô tả ngắn cho mỗi thuật toán. ## Thuật toán tổ hợp ### Thuật toán tổ hợp tổng quát * Thuật toán Brent: tìm
**_Robo Trái Cây_** (; tiếng Anh: _Fruity Robo_, Hán Việt: _Quả Bảo Đặc Công_) là một bộ phim hoạt hình của Trung Quốc do Công ty hoạt hình Lam Hồ (Quảng Châu) và Công ty
SIRO TRỊ HO THIÊN VƯƠNG PHẾ - THÀNH PHẦN VÀ CÔNG DỤNG Húng chanh : 5g Bạc Hà: 1g Cao lá thường xuân: 3g Kha tử: 2g Trần bì: 1,2g Hạnh nhân: 3,2g Tỏi đen:
**Phan Ngọc Nhi** (chữ Hán: 潘玉兒, ? - 501), là sủng phi của Phế Đế Đông Hôn hầu Tiêu Bảo Quyển triều Nam Tề trong lịch sử Trung Quốc. Tiêu Bảo Quyển chơi bời vô
Mứt mận Hòa An Nguyên Nhi được làm từ những trái mận tươi ngon, trồng theo hướng hữu cơ tại vùng đất Hòa An nổi tiếng. Với vị chua ngọt đặc trưng và quy trình
Mứt mận Hòa An Nguyên Nhi được làm từ những trái mận tươi ngon, trồng theo hướng hữu cơ tại vùng đất Hòa An nổi tiếng. Với vị chua ngọt đặc trưng và quy trình