LATEST

Tìm node Max và Min trong cây nhị phân tìm kiếm

Trong bài viết này, codehow sẽ hướng dẫn các bạn cách tìm node Max và Min trong cây nhị phân tìm kiếm. Bởi cây nhị phân tìm kiếm sinh ra là để tìm kiếm, vậy nên việc tìm kiếm node Max và Min là một chuyện đơn giản.

Chúng ta sẽ cùng nhau tìm hiểu về cách tìm node Max và Min trước, sau đó mình sẽ đưa ra ví dụ để thực hiện bằng ngôn ngữ C++. Hãy bắt đầu cùng mình thôi nhé!!

Tìm node Max và Min trong cây nhị phân tìm kiếm

Như các bạn đã biết thì cây nhị phân tìm kiếm là một cấu trúc lưu trữ dữ liệu đặc biệt dưới dạng cây. Các cây con bên trái luôn nhỏ hơn hoặc bằng node gốc, tương tự như vậy các cây con luôn lớn hơn hoặc bằng node gốc.

bai43 02 PNG

Ví vậy nếu chúng ta muốn tìm giá trị Max thì duyệt sang cây bên phải và tìm giá trị Min thì duyệt sang cây bên trái.

Tìm node Max trong cây nhị phân tìm kiếm

Như đã nói thì cây nhị phân tìm kiếm luôn luôn lưu giá trị của node lớn hơn node gốc. Vì vậy chỉ cần duyệt cây con bên phải là có thể tìm được node Max rồi. Cụ thể như sau:

  • Kiểm tra xem node bên phải có tồn tại hay không, nếu không có thì node gốc chính là node Max.
  • Trong trường hợp có tồn tại thì ta duyệt sang bên phải bằng cách gọi đệ quy, cứ như vậy cho đến khi hết cây ta sẽ được node Max.
int TimMax(TREE t)
{
    // CÁCH TỐI ƯU NHẤT
    // nếu node cha mà không tồn cây con phải - thì node cha này chính là node ngoài cùng nhất của cây con phải - cũng chính là node có giá trị lớn nhất
    if (t->pRight == NULL)
    {
        return t->data;
    }
    return TimMax(t->pRight); // duyệt đến node cuối cùng nhất bên cây con phải ==> để tìm giá trị lớn nhất
}

Tìm node Min trong cây nhị phân tìm kiếm

Đối với tìm node Min cũng được thực hiện tương tự. Nếu node bên trái của node gốc bằng NULL thì node gốc chính là node Min. Ngược lại nếu tồn tại node bên trái thì ta thực hiện gọi đệ quy để duyệt hết cây con bên trái và tìm node Min.

//hàm tìm giá trị MIN
int TimMin(TREE t)
{
    // CÁCH TỐI ƯU NHẤT
    // nếu node cha mà không tồn cây con trái - thì node cha này chính là node ngoài cùng nhất của cây con trái - cũng chính là node có giá trị nhỏ nhất
    if (t->pLeft == NULL)
    {
        return t->data;
    }
    return TimMin(t->pLeft); // duyệt đến node cuối cùng nhất bên cây con trái ==> để tìm giá trị nhỏ nhất
}

Ví dụ tìm node Max và Min trong cây nhị phân tìm kiếm

Để hiểu rõ hơn thì mình sẽ thực hiện một ví dụ tìm node Max và Min trong cây nhị phân tìm kiếm. Cụ thê các yêu cầu của chương trình như sau:

  • Xây dựng cấu trúc cây nhị phân tìm kiếm và cấu trúc node.
  • Tạo hàm thêm node vào cây.
  • Tạo hàm duyệt cây.
  • Hàm tìm node Max trong cây nhị phân tìm kiếm.
  • Hàm tìm node Min trong cây nhị phân tìm kiếm.
  • Tạo menu với các yêu cầu trên cho người dùng lựa chọn.

Bây giờ chúng ta sẽ đi thực hiện từng yêu cầu ở trên nhé.

Bước 1: Xây dựng cấu trúc cây nhị phân tìm kiếm và cấu trúc node.

// khai báo cấu trúc 1 cái node trong cây nhị phân tìm kiếm
struct node
{
    int data; // dữ liệu chứa trong 1 cái node
    struct node *pLeft; // con trỏ liên kết với cái node bên trái <=> cây con trái
    struct node *pRight; // con trỏ liên kết với cái node bên phải <=> cây con phải
};
typedef struct node NODE;
typedef NODE* TREE;
  
// hàm khởi tạo cây nhị phân tìm kiếm
void KhoiTaoCay(TREE &t)
{
    t = NULL;
}

Bước 2: Tạo hàm thêm node vào cây.

// hàm thêm 1 cái phần tử vào cây
void ThemNodeVaoCay(TREE &t, int x)
{
    // nếu cây rỗng
    if (t == NULL)
    {
        NODE *p = new NODE;
        p->data = x;
        p->pLeft = NULL;
        p->pRight = NULL;
        t = p;
    }
    else
    {
        // nếu phần tử thêm vào mà nhỏ hơn nút gốc thì sẽ duyệt qua bên trái
        if (x < t->data)
        {
            ThemNodeVaoCay(t->pLeft, x);
        }
        else if (x > t->data)
        {
            ThemNodeVaoCay(t->pRight, x);
        }
    }
}

Bước 3: Tạo hàm duyệt cây.

// hàm xuất phần tử trong cây nhị phân tìm kiếm
void NLR(TREE t)
{
    if (t != NULL)
    {
        // xử lí
        cout << t->data << "  ";
        NLR(t->pLeft);
        NLR(t->pRight);
    }
}

Bước 4: Hàm tìm node Max trong cây nhị phân tìm kiếm.

int TimMax(TREE t)
{
    // CÁCH TỐI ƯU NHẤT
    // nếu node cha mà không tồn cây con phải - thì node cha này chính là node ngoài cùng nhất của cây con phải - cũng chính là node có giá trị lớn nhất
    if (t->pRight == NULL)
    {
        return t->data;
    }
    return TimMax(t->pRight); // duyệt đến node cuối cùng nhất bên cây con phải ==> để tìm giá trị lớn nhất
}

Bước 5: Hàm tìm node Min trong cây nhị phân tìm kiếm.

//hàm tìm giá trị MIN
int TimMin(TREE t)
{
    // CÁCH TỐI ƯU NHẤT
    // nếu node cha mà không tồn cây con trái - thì node cha này chính là node ngoài cùng nhất của cây con trái - cũng chính là node có giá trị nhỏ nhất
    if (t->pLeft == NULL)
    {
        return t->data;
    }
    return TimMin(t->pLeft); // duyệt đến node cuối cùng nhất bên cây con trái ==> để tìm giá trị nhỏ nhất
}

Bước 6: Tạo menu với các yêu cầu trên cho người dùng lựa chọn.

// hàm nhập cây nhị phân tìm kiếm
void Menu(TREE &t)
{
    int luachon;
    while(true)
    {
        cout << "\n\n\t\t ============ MENU ============";
        cout << "\n1. Nhập phần tử cho cây";
        cout << "\n2. Duyệt cây";
        cout << "\n3. Giá trị MAX";
        cout << "\n4. Giá trị MIN";
        cout << "\n0. Thoát";
        cout << "\n\n\t\t =============  END  =============";
  
        cout << "\nNhập lựa chọn của bạn: ";
        cin >> luachon;
  
        if (luachon == 1)
        {
            int x;
            cout << "\nNhập giá trị: ";
            cin >> x;
            ThemNodeVaoCay(t, x);
        }
        else if (luachon == 2)
        {
            cout << "\nCây nhị phân tìm kiếm\n";
            NLR(t);
        }
        else if (luachon == 3)
        {
            cout << "\nGiá trị MAX: "<<TimMax(t);
        }
        else if (luachon == 4)
        {
            cout << "\nGiá trị MAX: "<<TimMin(t);
        }
        else
        {
            break;
        }
    }
}

Dưới đây là chường trình mình đã viết sẵn bằng ngôn ngữ C++, các bạn có thể tham khảo nhé.

#include<iostream>
using namespace std;
// khai báo cấu trúc 1 cái node trong cây nhị phân tìm kiếm
struct node
{
    int data; // dữ liệu chứa trong 1 cái node
    struct node *pLeft; // con trỏ liên kết với cái node bên trái <=> cây con trái
    struct node *pRight; // con trỏ liên kết với cái node bên phải <=> cây con phải
};
typedef struct node NODE;
typedef NODE* TREE;
  
// hàm khởi tạo cây nhị phân tìm kiếm
void KhoiTaoCay(TREE &t)
{
    t = NULL;
}
  
// hàm thêm 1 cái phần tử vào cây
void ThemNodeVaoCay(TREE &t, int x)
{
    // nếu cây rỗng
    if (t == NULL)
    {
        NODE *p = new NODE;
        p->data = x;
        p->pLeft = NULL;
        p->pRight = NULL;
        t = p;
    }
    else
    {
        // nếu phần tử thêm vào mà nhỏ hơn nút gốc thì sẽ duyệt qua bên trái
        if (x < t->data)
        {
            ThemNodeVaoCay(t->pLeft, x);
        }
        else if (x > t->data)
        {
            ThemNodeVaoCay(t->pRight, x);
        }
    }
}
  
// hàm xuất phần tử trong cây nhị phân tìm kiếm
void NLR(TREE t)
{
    if (t != NULL)
    {
        // xử lí
        cout << t->data << "  ";
        NLR(t->pLeft);
        NLR(t->pRight);
    }
}
  
//Hàm tìm giá trị MAX
//------cách 1------------
// int MAX = INT_MIN; // gán cho biến MAX là giá trị nhỏ nhất của kiểu integer
// //// hàm tìm phần tử lớn nhất trong cây
// void TimMax(TREE t)
// {
//  if (t != NULL)
//  {
//      // xử lí
//      if (MAX < t->data)
//      {
//          MAX = t->data; // cập nhật lại giá trị cho biến MAX
//      }
//      TimMax(t->pLeft);
//      TimMax(t->pRight);
//  }
// }
int TimMax(TREE t)
{
    // CÁCH TỐI ƯU NHẤT
    // nếu node cha mà không tồn cây con phải - thì node cha này chính là node ngoài cùng nhất của cây con phải - cũng chính là node có giá trị lớn nhất
    if (t->pRight == NULL)
    {
        return t->data;
    }
    return TimMax(t->pRight); // duyệt đến node cuối cùng nhất bên cây con phải ==> để tìm giá trị lớn nhất
}
//hàm tìm giá trị MIN
int TimMin(TREE t)
{
    // CÁCH TỐI ƯU NHẤT
    // nếu node cha mà không tồn cây con trái - thì node cha này chính là node ngoài cùng nhất của cây con trái - cũng chính là node có giá trị nhỏ nhất
    if (t->pLeft == NULL)
    {
        return t->data;
    }
    return TimMin(t->pLeft); // duyệt đến node cuối cùng nhất bên cây con trái ==> để tìm giá trị nhỏ nhất
}
  
// hàm nhập cây nhị phân tìm kiếm
void Menu(TREE &t)
{
    int luachon;
    while(true)
    {
        cout << "\n\n\t\t ============ MENU ============";
        cout << "\n1. Nhập phần tử cho cây";
        cout << "\n2. Duyệt cây";
        cout << "\n3. Giá trị MAX";
        cout << "\n4. Giá trị MIN";
        cout << "\n0. Thoát";
        cout << "\n\n\t\t =============  END  =============";
  
        cout << "\nNhập lựa chọn của bạn: ";
        cin >> luachon;
  
        if (luachon == 1)
        {
            int x;
            cout << "\nNhập giá trị: ";
            cin >> x;
            ThemNodeVaoCay(t, x);
        }
        else if (luachon == 2)
        {
            cout << "\nCây nhị phân tìm kiếm\n";
            NLR(t);
        }
        else if (luachon == 3)
        {
            cout << "\nGiá trị MAX: "<<TimMax(t);
        }
        else if (luachon == 4)
        {
            cout << "\nGiá trị MAX: "<<TimMin(t);
        }
        else
        {
            break;
        }
    }
}
  
int main()
{
    TREE t;
    KhoiTaoCay(t);
    Menu(t);
  
    cout<<"\n---------------------------------\n";
  cout<<"Chương trình này được đăng tại codehow.net";
}

Kết quả:

bai43 01 PNG

Cùng chuyên mục:

Xóa node khỏi cây nhị phân tìm kiếm

Xóa node khỏi cây nhị phân tìm kiếm

Xuất node con và node lá trong cây nhị phân tìm kiếm

Xuất node con và node lá trong cây nhị phân tìm kiếm

Tìm kiếm trên cây nhị phân tìm kiếm

Tìm kiếm trên cây nhị phân tìm kiếm

Duyệt cây nhị phân tìm kiếm

Duyệt cây nhị phân tìm kiếm

Thêm node vào cây nhị phân tìm kiếm

Thêm node vào cây nhị phân tìm kiếm

Cây nhị phân (Binary tree) là gì? Cơ chế hoạt động của nó

Cây nhị phân (Binary tree) là gì? Cơ chế hoạt động của nó

Cách gộp hai danh sách liên kết đôi

Cách gộp hai danh sách liên kết đôi

Tìm kiếm phần tử trong DSLK đôi

Tìm kiếm phần tử trong DSLK đôi

Xóa node trong DSLK đôi

Xóa node trong DSLK đôi

Chèn node (Insert node) vào DSLK đôi

Chèn node (Insert node) vào DSLK đôi

Duyệt danh sách liên kết đôi

Duyệt danh sách liên kết đôi

Tạo node mới trong DSLK đôi

Tạo node mới trong DSLK đôi

DSLK đôi là gì? Cấu trúc dữ liệu của DSLK đôi

DSLK đôi là gì? Cấu trúc dữ liệu của DSLK đôi

Quản lý sinh viên bằng DSLK đơn

Quản lý sinh viên bằng DSLK đơn

Tìm kiếm và sắp xếp trong DSLK đơn

Tìm kiếm và sắp xếp trong DSLK đơn

Xóa node (Delete node) trong DSLK đơn

Xóa node (Delete node) trong DSLK đơn

Chèn node (Insert node) vào DSLK đơn

Chèn node (Insert node) vào DSLK đơn

Tạo node mới trong DSLK đơn

Tạo node mới trong DSLK đơn

Cấu trúc dữ liệu của DSLK đơn

Cấu trúc dữ liệu của DSLK đơn

Danh sách liên kết (Linked List) là gì? Các loại danh sách liên kết

Danh sách liên kết (Linked List) là gì? Các loại danh sách liên kết