Thao tác tìm kiếm là rất cần thiết trong việc thực hiện các thao tác như chèn, xóa hay sửa một phần tử có trong cây. Hay đơn giản chỉ là việc tìm kiếm và chọn ra phần tử phù hợp với một yêu cầu nào đó có trong cây! Trong cấu trúc cây khi thực hiện thao tác tìm kiếm ta có thể sử dụng theo 2 phương pháp đệ quy và không đệ quy.
1.Tìm kiếm phần tử trong cây theo phương pháp đệ quy
Với yêu cầu tìm kiếm một phần tử có dữ liệu x nào đó thuộc trong cây.

Đối với phương pháp tìm kiếm có sử dụng đệ quy ta cần thực hiện kiểm tra một số điều kiện sau đây:
- Nếu root->data == x, nghĩa là node gốc của cây có data bằng với x thì dừng việc tìm kiếm và return root; (Đây là điều kiện dừng của hàm tìm kiếm theo phương pháp đệ quy)
- Nếu root->data > x, nghĩa là node gốc của cây có data lớn hơn x thì ta sẽ thực hiện gọi đệ quy lại hàm tìm kiếm theo cây con trái
- Nếu root->data < x, nghĩa là node gốc của cây có data nhỏ hơn x thì ta sẽ thực hiện gọi đệ quy lại hàm tìm kiếm theo cây con phải
Để hiểu rõ hơn các bước trên, mời bạn đọc thêm đoạn code dưới đây:
Hàm SearchNodeRecursion(Tree root, int x) nhận tham số là node gốc của cây Tree root và int x là phần tử cần tìm kiếm:
Node* SearchNodeRecursion(Tree root, int x){
//neu cay khong rong
if(root!=NULL){
//neu data cua node goc bang x can tim
if(root->data == x){
//tra ve node goc cua cay
return root;
}
//neu data cua node goc lon hon x can tim
if(root->data > x){
//goi lai ham tim kiem theo cay con trai
return SearchNodeRecursion(root->left, x);
}else{//nguoc lai data cua node goc nho hon x can tim
//goi lai ham tim kiem theo cay con phai
return SearchNodeRecursion(root->right, x);
}
}
//neu khong tim thay node co data bang x thi tra ve rong
return NULL;
}
2.Tìm kiếm phần tử trong cây không sử dụng đệ quy
Với yêu cần tìm một phần tử x với phương pháp tìm kiếm phần tử không sử dụng đệ quy việc tìm kiếm một phần tử chỉ đơn giản thực hiện các bước bên dưới đây:
- Dùng vòng lăp duyệt từ node gốc đến hết các node trong cây
- Trong vòng lặp kiểm tra điều kiện nếu tìm thấy node có dữ liệu bằng với x cần tìm thì trả về chính node đang được xét
- Nếu x < data của node đang xét trong vòng lặp thì để vòng lặp tiến theo cây con trái
- Ngược lại nếu x > data của node đang xét trong vòng lặp thì để vòng lặp tiến theo cây con phải
Mời bạn đọc cùng tham khảo đoạn code dưới đây để hiểu hơn về các bước trên.
Node* SearchNode(Tree root, int x){
//tao va gan node p bang node goc
Node *p = root;
//duyet tu node goc den het cay
while (p != NULL){
//neu co data cua node p dang xet bang x can tim
if(p->data==x){
//tra ve node dang duoc xet
return p;
}else{
//neu phan tu x can tim nho hon data cua node dang xet
if(x < p->data){
//tim kiem theo cay con trai
p = p->left;
}else{//nguoc lai neu phan tu x can tim lon hon data cua node dang xet
//tim kiem theo cay con phai
p = p->right;
}
}
}
//neu khong tim thay node co data bang x thi tra ve rong
return NULL;
}
3.Chương trình tìm kiếm phần tử trong cây nhị phân hoàn chỉnh
Chương trình dưới đây sẽ là một chương trình hoàn chỉnh, sử dụng lại hai hàm tìm kiếm theo phương pháp đệ quy và không dùng đệ quy để tìm kiếm một phần từ x. Kết quả nhận được khi sử dụng cả hai hàm là giống nhau!
#include <stdio.h>
#include <stdlib.h>
typedef struct Node{
//khai bao du lieu cua node co kieu du lieu int
int data;
//khai bao con tro den cay con trai
Node* left;
//khai bao con tro den cay con phai
Node* right;
};
typedef struct Node* Tree;
Tree root;
void Init (Tree &root){
//gan node goc ve NULL
root = NULL;
}
Node* CreateNode (int x){
//tao node moi
Node* p = new Node;
//neu cay nhi phan khong rong
if (p != NULL){
//gan cay con trai va cay con phai mac dinh bang NULL
p->left = NULL;
p->right = NULL;
//gan data bang x
p->data = x;
}
//tra ve node p
return p;
}
int InsertNode(Tree &root, Node*p){
//neu node root khac rong thi thuc hien them vao cay
if (root != NULL){
//neu 2 data cua 2 node bang nhau thi ket thuc
if (root->data==p->data){
return 0;
}
//neu khoa cua root lon hon khoa cua p thi goi de quy trai
if (root->data > p->data){
return InsertNode(root->left, p);
}
else{//neu khoa cua root nho hon khoa cua p thi goi de quy phai
return InsertNode(root->right,p);
}
}else { //truong hop neu node root la rong thi them node p vao node root
root = p;
}
}
void Input(Tree &root){
int n;
printf ("NHAP SO LUONG NODE CAN THEM: ");
scanf("%d",&n);
for(int i=1; i<=n;i++){
int x;
printf ("NHAP DATA CUA NODE %d: ",i);
scanf("%d",&x);
//tao node p co data = x
Node* p = CreateNode(x);
//them node p co data x vao trong cay
InsertNode(root, p);
}
}
void NLR(Tree root){
if (root!=NULL){
//hien thi du lieu cua tung node sau khi duyet
printf("%d \t",root->data);
//su dung de quy de duyet tiep cay con trai
NLR(root->left);
//su dung de quy de duyet tiep cay con phai
NLR(root->right);
}
}
Node* SearchNodeRecursion(Tree root, int x){
//neu cay khong rong
if(root!=NULL){
//neu data cua node goc bang x can tim
if(root->data == x){
//tra ve node goc cua cay
return root;
}
//neu data cua node goc lon hon x can tim
if(root->data > x){
//goi lai ham tim kiem theo cay con trai
return SearchNodeRecursion(root->left, x);
}else{//nguoc lai data cua node goc nho hon x can tim
//goi lai ham tim kiem theo cay con phai
return SearchNodeRecursion(root->right, x);
}
}
//neu khong tim thay node co data bang x thi tra ve rong
return NULL;
}
Node* SearchNode(Tree root, int x){
//tao va gan node p bang node goc
Node *p = root;
//duyet tu node goc den het cay
while (p != NULL){
//neu co data cua node p dang xet bang x can tim
if(p->data==x){
//tra ve node dang duoc xet
return p;
}else{
//neu phan tu x can tim nho hon data cua node dang xet
if(x < p->data){
//tim kiem theo cay con trai
p = p->left;
}else{//nguoc lai neu phan tu x can tim lon hon data cua node dang xet
//tim kiem theo cay con phai
p = p->right;
}
}
}
//neu khong tim thay node co data bang x thi tra ve rong
return NULL;
}
int main(){
//tao cay voi node goc la root
Tree root;
//khoi tao cay
Init(root);
//nhap n phan tu vao cay
Input(root);
//duyet cay theo NLR
printf("Duyet cay theo NLR\n");
NLR(root);
printf("\n");
//tim kiem
int x = 5;
//tim kiem theo ham co su dung de quy
Node *p = SearchNodeRecursion(root,x);
if(p == NULL){//neu node p la rong
printf("Khong tim thay node");
}else{
printf("Tim thay phan tu %d theo phuong phap de quy", x);
}
printf("\n");
//tim kiem theo ham khong dung de quy
Node *k = SearchNode(root,x);
if(k == NULL){ //neu node k la rong
printf("Khong tim thay node");
}else{
printf("Tim thay phan tu %d khong dung de quy", x);
}
}
| NHAP SO LUONG NODE CAN THEM: 5
NHAP DATA CUA NODE 1: 6 NHAP DATA CUA NODE 2: 5 NHAP DATA CUA NODE 3: 8 NHAP DATA CUA NODE 4: 3 NHAP DATA CUA NODE 5: 0 Duyet cay theo NLR 6 5 3 0 8 Tim thay phan tu 5 theo phuong phap de quy Tim thay phan tu 5 khong dung de quy |


