Professional Documents
Culture Documents
Tìm kiếm thông tin trong danh sách đặc
Tìm kiếm thông tin trong danh sách đặc
Bắt đầu
Mảng a[MAXSIZE], n, i
=0
sai
i< Kết thúc
đúng
g
đúng
i< g
sai
i = i +1
Ví dụ minh họa:
10 2 1 14 5 9 30 7
a
0 7
0
Lần 1: i = 0
x=1
10 2 1 14 5 9 30 7
Lần 2: i = 1
x=1
10 2 1 14 5 9 30 7
Lần 3: i = 2
x=1
10 2 1 14 5 9 30 7
Lần 4: Dừng
#code giải thuật
// Hàm tìm kiếm tuần tự
Sử dụng vòng lập for
int linearSearch_For(ItemType a[], int n, ItemType x)
{
for (int i = 0; i < n; i++)
{
if (a[i] == x)
return i; // Trả về vị trí của phần tử nếu tìm thấy
}
return -1; // Trả về 0 nếu không tìm thấy phần tử
}
Sử dụng While
int linearSearch_While(ItemType a[], int n, ItemType x)
{
int i = 0;
while (i < n) && (a[i] != x)
i ++;
if (i == n)
return -1;// Không tìm thấy x
else
return i; // Tìm thấy x tại vị trí i
}
- Bước 1: Khởi gán giá trị ban đầu cho các biến (tìm kiếm trên toàn bộ dãy)
Left = 0; Right = n - 1;
- Bước 2: Tính giả trị biển Mid: Mid = (Left + Right)/2;
+ Nếu (a[Mid] = x): Tìm thấy. Dùng
+ Nếu (a[Mid] > x): Chuẩn bị tìm x trong dãy con aLeft..amid - 1: Right = Mid - 1;
+ Nếu (a[Mid] <x): Chuẩn bị tìm x trong dãy con amid + 1..aright: Left = Mid + 1;
- Bước 3
+ Nếu (Left ≤ Right): Dây hiện hành vẫn còn phần tử. Quay lại Bước 2.
+ Ngược lại: Dây hiện hành hết phần tử. Dừng.
Ví dụ minh họa:
Cho dãy số gồm 8 phần tử
1 2 5 7 9 10 14 30
x=14
7
1 2 5 9 10 14 30
x=14
1 2 5 7 9 10 14 30
x=14
1 2 5 7 9 10 14 30
Lần 4: Dừng
Hàm BinarySearch cũng chỉ đơn giản sử dụng một vòng lặp để duyệt qua các phần tử
trong mảng. Tuy nhiên, vòng lặp này sẽ không duyệt qua hết tất cả các phần tử như đối
với tìm kiếm tuyến tính. Tư tưởng cài đặt của hàm này cũng giống như đối với
LinearSearch, nghĩa là khi kết thúc vòng lặp cũng có hai khả năng xảy ra:
Chỉ số Left vẫn còn bé hơn hoặc bằng chỉ số Right. Điều này có nghĩa là đã có
một phần tử nào đó bằng với giá trị x cần tìm, cụ thể là giá trị của phân tử Mid. Do
đó, hàm sẽ trả về giá trị nằm trong biến Mid.
Chỉ số Left đã vượt qua chỉ số Right, nghĩa là đã duyệt qua hết các phần tử trong
mảng mà không tìm thấy phần tử nào có giá trị bằng x. Do đó, hàm trả về giá trị -
1.
Hàm đệ quy
int BinarySearch(int a[], int Left, int Right, int x) {
// Kiểm tra nếu chỉ số bắt đầu lớn hơn chỉ số kết thúc
if (Left > Right)
return -1; // Trả về -1 nếu không tìm thấy phần tử
int Mid = (Left + Right) / 2; // Tính chỉ số giữa của phạm vi tìm kiếm
if (x == a[Mid])
return Mid; // Trả về chỉ số nếu tìm thấy phần tử
else if (x < a[Mid])
return BinarySearch(a, Left, Mid - 1, x); // Tìm kiếm trong nửa đầu của mảng
else
return BinarySearch(a, Mid + 1, Right, x); // Tìm kiếm trong nửa sau của mảng
}
Nhận xét
Giải thuật tìm nhị phân phụ thuộc vào thứ tự của các phần tử trong mảng để
định hướng trong quá trình tìm kiếm, do vậy chỉ áp dụng được cho những dãy đã có
thứ tự.
Giải thuật tìm kiếm nhị phân tiết kiệm thời gian hơn rất nhiều so với giải thuật
tìm kiếm tuyến tính do O Nhị phân (log2n) < O Tuyến tính(n). Tuy nhiên khi muốn áp dụng
giải thuật tìm kiếm nhị phân cần phải xét đến thời gian sắp xếp dãy số để thỏa điều
kiện dãy số có thứ tự, thời gian này là không nhỏ, và khi dãy số biến động cần phải
tiến hành sắp xếp lại, … tất cả các nhu cầu đó tạo ra khuyết điểm chính cho giải
thuật tìm kiếm nhị phân.