[Thuật toán] Tìm kiếm nhị phân:

Share:


Là phương pháp tìm kiếm phổ biến, dựa trên dãy đã sắp xếp thứ tự. Nội dung của giải thuật này là : lấy khoá X cần tìm so sánh với phần tử ở giữa dãy , với vị trí phần tử ở giữa được xác định là mid = (hight+low)/2, trong đó cận dưới low=0, cận trên hight= n-1. Vì dãy đã sắp xếp nên có các trường hợp sau xảy ra: 
nếu X= A[mid] thì cho ra kết quả (cần tìm X trong dãy A[i])
nếu X < A[mid] => X thuộc khoảng [A[low];A[mid-1] ] lại tiếp tục tìm kiếm nhị phân X trong dãy từ A[low]-> A[mid -1]
Nếu X> A[mid]=> X thuộc khoảng [A[mid+1], A[hight]], lại tiếp tục tìm kiếm nhị phân X trong dãy từ A[mid + 1], A[hight]
Quá trình tìm cho tới khi tìm ra X hoặc không tìm được X trong dãy

Có thể viết thuật toán tìm kiếm nhị phân theo vòng lặp hoặc theo đệ quy đều được.
Ta sẽ viết luôn thủ tục hàm tìm kiếm nhị phân theo hai cách:
Hàm tìm kiếm nhị phân mà chúng ta viết là : 
Binary_Search(Usertype *A, Usertype X, int n);
Trong đó: Usertype là cấu trúc dữ liệu mà ta cần tìm kiếm, có thể là các kiểu đơn giản có sẵn: int, long , float, doublle., char… hoặc các kiểu do người dùng định nghĩa, có thể là một cấu trúc nào đó (ví dụ như Struct SinhVien, SoPhuc….)
Mảng A có n phần tử đã được sắp xếp. Do đó trước khi thực hiện thao tác tìm kiếm thì chúng ta phải thực hiện thao tác sắp xếp dãy đã.

Viết dưới dạng vòng lặp : 


int Binary_Search(Usertype *A, Usertype X, int n) // hàm trả về là vị trí của X trong dãy
{
  1.     int mid,low=o,hight=n-1;
  2.     while(low<=hight) // lap neu can duoi van nho hon can tren
  3.        {
  4.     mid=(low+hight)/2;  //xác định vị trí phần tử ở giữa
  5.     if(X>A[mid]) low=mid+1;      // X thuộc [mid+1,hight]
  6.             else        if(X<A[mid]) hight=mid-1;   // X thuộc đoạn [low,mid-1]
  7.     else   return(mid); //trả về vị trí của X trong dãy
  8.    }
  9.         return(-1); // nếu X không thuộc dãy thì trả về giá trị của hàm là -1
  10. }

Viết dưới dạng hàm đệ quy:
C Code:
  1. int Binary_Search(Usertype *A, Usertype X, int i,int j)  // hàm trả về là vị trí của X trong dãy
  2. {
  3.     int mid=(i+j)/2;
  4.     if(X>A[mid]&&i<mid)
  5.         return(Binary_Search(A,X,mid+1,j));
  6.     else if(X<A[mid]&&j>mid)
  7.         return(Binary_Search(A,X,i,mid-1));
  8.     else if(X==A[mid])
  9.         return(mid);
  10.     return(-1); // tra lai gia tri la -1 nếu không tìm thấy X
  11. }

Chương trình cài đặt thuật toán cho tìm kiếm nhị phân một số nguyên trong dãy như sau:
C Code:
  1. #include    <stdio.h>
  2. #include    <conio.h>
  3. #include    <stdlib.h>
  4. #include    <alloc.h>
  5. #include    <dos.h>
  6. int Binary_Search( int *, int, int);
  7. void Bubble(int *, int);
  8. void Init(int *, int);
  9. int Binary_Search( int *A, int X, int n) {
  10.     int mid, low = 0, hight = n-1;
  11.     while (low<=hight){
  12.         mid = (low +hight)/2;
  13.         if (>A[mid] ) low = mid +1;
  14.         else if (X<A[mid] ) hight = mid -1;
  15.         else    return (mid);
  16.     }
  17.     return(-1);
  18. }
  19. void Init(int *A, int n){
  20.     int i;
  21.     printf("\n Tao lap day so:");
  22.     for (i=0; i<n;i++){
  23.         A[i]=random(1000);
  24.         printf("%5d",A[i]);
  25.     }
  26.     delay(1000);
  27. }
  28. void Bubble(int *A, int n){
  29.     register i,j,temp;
  30.     for (i=1; i<n; i++){
  31.         for (j=n-1; j>=i;j--){
  32.             if (A[j-1]>A[j]){
  33.                 temp=A[j-1];
  34.                 A[j-1]=A[j];
  35.                 A[j]=temp;
  36.             }
  37.         }
  38.         printf("\n Ket qua lan:%d", i);
  39.         In(A,n);
  40.     }
  41. }
  42. void In(int *A, int n){
  43.     register int i;
  44.     for(i=0;i<n;i++)
  45.         printf("%5d",A[i]);
  46.     delay(1000);
  47. }
  48. void main(void){
  49.     int *A,n, X, k;clrscr();
  50.     printf("\n Nhap n="); scanf("%d",&n);
  51.     printf(“\n Sè cÇn t×m X=); scanf(%d”,&X);
  52.     A=(int *) malloc(n*sizeof(int));
  53.     Init(A,n);Bubble(A,n); k= Binary_Search(A, X, n);
  54.     if ( k>0)
  55.         printf (“\n %d ë vÞ trÝ sè %d”, X, k);
  56.     else
  57.         printf(“\n %d kh«ng thuéc d·y”);
  58.     getch();
  59.     free(A);
  60. }
Download code tìm kiếm nhị phân miễn phí