LATEST

Thuật toán tìm kiếm nhị phần (Binary Search) trong C / C++

Trong bài viết này, codehow sẽ giới thiệu đến các bạn thuật toán tìm kiếm nhị phân (Binary Search) trong C / C++. Đối với thuật toán tìm kiếm này thì được tối ưu hơn khá nhiều so với thuật toán tìm kiếm tuyến tính (Linear Search).

Bây giờ chúng ta sẽ bắt đầu tìm hiểu về thuật toán tìm kiếm nhị phần là gì? Sau đó mình sẽ đưa ra thuật toán kèm với ví dụ cho các bạn dễ hiểu nhé.

Tìm kiếm nhị phân (Binary Search) là gì?

Thuật toán tìm kiếm nhị phần (Binary Search) đúng như tên gọi của nó, được dùng để tìm kiếm một giá trị x trên một mảng đã được sắp xếp.

Nó còn được gọi với cái tên khác là tìm kiếm một nữa. Bởi vì nó chia nữa mảng ra để so sánh, thay vì phải duyệt tất cả các phần tử như thuật toán tìm kiếm tuyến tính.

bai9 01 gif

Như các bạn đã thấy ở hình trên, thuật toán tìm kiếm nhị phân thực hiện tìm kiếm trên mảng đã sắp xếp bằng cách liên tục chia mảng thành một nữa.

Đầu tiên thuật toán sẽ bắt đầu tìm kiếm từ đầu mảng đến cuối mảng. Nếu giá trị cần tìm nhỏ hơn giá trị ở giữa mảng, thì khi đó thu hẹp phạm vi tìm kiếm từ đầu mảng đến giữa mảng. Ngược lại nếu giá trị cần tìm lớn hơn giá trị giữa mảng thì thực hiện tìm kiếm ở phần cuối mảng.

Cứ như vậy chia nửa mảng và tìm kiếm cho đến khi tìm được giá trị.

*Lưu ý: Đối với phương pháp tìm kiếm nhị phân (Binary Search) thì yêu cầu mảng phải được sắp xếp.

Thuật toán tìm kiếm nhị phân đã tối ưu hơn khá nhiều so với thuật toán tìm kiếm tuyến tính. Tuy nhiên, nó vẫn chỉ sử dụng trong các mảng nhỏ và đã được sắp xếp, đổi với các mảng lớn chúng ta không nên sử dụng nó.

Thuật toán tìm kiếm nhị phân (Binary Search) trong C / C++

Như đã nói thì thuật toán tìm kiếm nhị phân chỉ dùng được với mảng đã sắp xếp. Vậy nên chúng ta cần đảm bảo rằng mảng đã được sắp xếp nhé.

Dưới đây là thuật toán tìm kiếm nhị phân (Binary Search) trong C / C++. Các bạn hãy xem qua nó đã nhé, mình sẽ giải thích ngay bên dưới kèm theo ví dụ cụ thể về nó.

int binarySearch(int arr[], int left, int right, int x) {
    int middle;
    while(left <= right) {
        // Lấy vị trí ở giữa left và right
        middle = (left + right) / 2;
        // Nếu phần từ ở giữa bằng x thì trả về
        // vị trí
        if (arr[middle] == x)
            return middle;
        // Nếu x lớn hơn phần tử ở giữa thì
        // chắc chắn nó nằm bên phải.
        // Chỉ định left phần từ ở giữa + 1
        if (x > arr[middle])
            left = middle + 1;
        else
            //Ngược lại
            right = middle - 1;
    }
    //Trả về -1 nếu không tìm thấy gía trị trong mảng.
    return -1;
}

Trong đó:

  • arr[] là mảng cần tìm đã được sắp xếp.
  • left là vị trí đầu của mảng ( = 0).
  • right là vị trí cuối của mảng ( = n - 1).
  • x là giá trị cần tìm.

Giải thích thuật toán:

  1. Duyệt các phần tử trong khoảng từ left -> right, lúc này giá trị của left là 0 và của right là n - 1 (độ dài mảng trừ đi 1).
  2. So sánh x với giá trị middle (giữa mảng), nếu x = middle thì trả về vị trí và thoát vòng lặp.
  3. Nếu x < middle thì nghĩa là x nằm bên trái mảng, tức là từ left -> middle -1.
  4. Nếu x > middle thì nghĩa là x nằm bên phải mảng, tức là từ middle + 1 -> right.
  5. Cứ tiếp tục vòng lặp cho đến khi tìm thấy giá trị x.

Dưới đây mình sẽ thực hiện chương trình tìm kiếm giá trị x sử dụng thuật toán tìm kiếm nhị phân (Binary Search) trong C / C++. Chương trình được viết bằng hai ngôn ngữ khác nhau là C và C++, các bạn có thể tham khảo nhé.

Chương trình C:

#include <stdio.h>
#include <stdbool.h>

void sort_numbers_ascending(int number[], int count)
{
   int temp, i, j, k;
   for (j = 0; j < count; ++j)
   {
      for (k = j + 1; k < count; ++k)
      {
         if (number[j] > number[k])
         {
            temp = number[j];
            number[j] = number[k];
            number[k] = temp;
         }
      }
   }
   printf("Các số sau khi được sắp xếp tăng dần: ");
   for (i = 0; i < count; ++i)
      printf("%d ",number[i]);
}

//Hàm tìm kiếm nhi phân
int binarySearch(int arr[], int left, int right, int x) {
    int middle;
    while(left <= right) {
        // Lấy vị trí ở giữa left và right
        middle = (left + right) / 2;
        // Nếu phần từ ở giữa bằng x thì trả về
        // vị trí
        if (arr[middle] == x)
            return middle;
        // Nếu x lớn hơn phần tử ở giữa thì
        // chắc chắn nó nằm bên phải.
        // Chỉ định left phần từ ở giữa + 1
        if (x > arr[middle])
            left = middle + 1;
        else
            //Ngược lại
            right = middle - 1;
    }
    //Trả về -1 nếu không tìm thấy gía trị trong mảng.
    return -1;
}

int main(void) {
  int n,x, result;
    do{
      printf("Nhập vào số lượng phần tử của mảng: ");
      scanf("%d", &n);
      if(n <= 0) printf("Vui lòng nhập số lượng phần tử lớn hơn 0!!!\n");
    }while(n <= 0);
    
    int a[n];
    //nhập các phần tử mảng
    for(int i=0; i<n; i++){
         printf("Nhập vào phần tử a[%d]: ",i);
         scanf("%d",&a[i]);
    }
    
    sort_numbers_ascending(a,n);
  
    printf("\nNhập giá trị x cần tìm: ");
    scanf("%d", &x);
    result = binarySearch(a, 0, n-1, x);
    if(result == -1) printf("\nKhông tìm thấy giá trị %d trong mảng.\n",x);
    else printf("\nĐã tìm thấy giá trị %d tại vị trí %d",x,result);

    printf("\n----------------------------\n");
    printf("Chương trình này được đăng tại codehow.net");
  return 0;
}

Kết quả:

bai9 03 png

Chương trình C++:

#include <iostream>
using namespace std;

void sort_numbers_ascending(int number[], int count)
{
   int temp, i, j, k;
   for (j = 0; j < count; ++j)
   {
      for (k = j + 1; k < count; ++k)
      {
         if (number[j] > number[k])
         {
            temp = number[j];
            number[j] = number[k];
            number[k] = temp;
         }
      }
   }
   cout<<"Các số sau khi được sắp xếp tăng dần: ";
   for (i = 0; i < count; ++i)
      cout<< number[i]<<" ";
}

int binarySearch(int arr[], int left, int right, int x) {
    int middle;
    while(left <= right) {
        // Lấy vị trí ở giữa left và right
        middle = (left + right) / 2;
        // Nếu phần từ ở giữa bằng x thì trả về
        // vị trí
        if (arr[middle] == x)
            return middle;
        // Nếu x lớn hơn phần tử ở giữa thì
        // chắc chắn nó nằm bên phải.
        // Chỉ định left phần từ ở giữa + 1
        if (x > arr[middle])
            left = middle + 1;
        else
            //Ngược lại
            right = middle - 1;
    }
    //Trả về -1 nếu không tìm thấy gía trị trong mảng.
    return -1;
}

int main() {
  int n,x, result;
    do{
      cout << "Nhập vào số lượng phần tử của mảng: ";
      cin >> n;
      if(n <= 0) cout<<"Vui lòng nhập số lượng phần tử lớn hơn 0!!!\n";
    }while(n <= 0);
    
    int a[n];
    //nhập các phần tử mảng
    for(int i=0; i<n; i++){
         cout << "Nhập vào phần tử a[" << i << "]: ";
         cin >> a[i];
    }
    sort_numbers_ascending(a,n);
  
    cout<<"\nNhập giá trị x cần tìm: ";
    cin>>x;
    result = binarySearch(a, 0, n-1, x);
    if(result == -1) cout<<"Không tìm thấy giá trị "<<x<<" trong mảng.\n";
    else cout<<"Đã tìm thấy giá trị "<<x<<" tại vị trí "<<result;

    cout<<"\n----------------------------\n";
    cout<<"Chương trình này được đăng tại codehow.net";
}

Kết quả:

bai9 02 png

Như vậy là chúng ta đã cùng nhau tìm hiểu về thuật toán tìm kiếm nhị phân (Binary Search) trong C / C++. Còn rất nhiều thuật toán hay ở các bài sau nữa, các bạn chú ý theo dõi nhé. Cảm ơn các bạn rất nhiều !!!

Cùng chuyên mục:

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

Sử dụng đệ quy để giải bài toán tháp Hà Nội

Sử dụng đệ quy để giải bài toán tháp Hà Nội

Đệ quy tương hỗ (Mutual Recursion) trong C / C++

Đệ quy tương hỗ (Mutual Recursion) trong C / C++

Đệ quy lồng (Nested Recursion) trong C / C++

Đệ quy lồng (Nested Recursion) trong C / C++

Đệ quy đa tuyến (Exponential Recursion) trong C / C++

Đệ quy đa tuyến (Exponential Recursion) trong C / C++

Đệ quy nhị phân (Binary Recursion) trong C / C++

Đệ quy nhị phân (Binary Recursion) trong C / C++

Đệ quy đuôi (Tail Recursion) trong C / C++

Đệ quy đuôi (Tail Recursion) trong C / C++

Đệ quy tuyến tính (Linear Recursion) trong C / C++

Đệ quy tuyến tính (Linear Recursion) trong C / C++

Hàm đệ quy là gì? Các loại hàm đệ quy trong C / C++

Hàm đệ quy là gì? Các loại hàm đệ quy trong C / C++

Thuật toán sắp xếp Quick Sort trong C / C++

Thuật toán sắp xếp Quick Sort trong C / C++

Thuật toán sắp xếp trộn (Merge Sort) trong C / C++

Thuật toán sắp xếp trộn (Merge Sort) trong C / C++

Thuật toán sắp xếp chọn (Selection Sort) trong C / C++

Thuật toán sắp xếp chọn (Selection Sort) trong C / C++

Thuật toán sắp xếp chèn (Insertion Sort) trong C / C++

Thuật toán sắp xếp chèn (Insertion Sort) trong C / C++

Thuật toán sắp xếp nổi bọt (Bubble Sort) trong C / C++

Thuật toán sắp xếp nổi bọt (Bubble Sort) trong C / C++

Thuật toán tìm kiếm nội suy (Interpolation Search) trong C / C++

Thuật toán tìm kiếm nội suy (Interpolation Search) trong C / C++

Thuật toán tìm kiếm tuyến tính (Linear Search) trong C / C++

Thuật toán tìm kiếm tuyến tính (Linear Search) trong C / C++

Thuật toán kiểm tra năm nhuận trong C / C++

Thuật toán kiểm tra năm nhuận trong C / C++

Thuật toán kiểm tra số chẵn lẻ trong C / C++

Thuật toán kiểm tra số chẵn lẻ trong C / C++

Thuật toán tính lũy thừa trong C / C++

Thuật toán tính lũy thừa trong C / C++

Thuật toán tìm ước chung lớn nhất trong C / C++

Thuật toán tìm ước chung lớn nhất trong C / C++

Top