Download as docx, pdf, or txt
Download as docx, pdf, or txt
You are on page 1of 9

Tìm kiếm thông tin trong danh sách đặc

1) Phương pháp tìm kiếm tuần tự ( Linear Search)


Giải thuật:
Gọi x là giá trị cần tìm và a là mảng chứa dữ liệu có n phần tử
Bước 1: Bắt đầu từ phần tử đầu tiên của danh sách (khởi gán giá trị biếni: i = 0).
Bước 2: So sánh phần tử hiện tại a[i] với phần tử cần tìm x.
Có 2 khả năng có thể xảy ra
 Nếu phần tử hiện tại bằng phần tử cần tìm (a[i] == x), trả về vị trí thứ i của phần tử
đó trong danh sách và dừng.
 Ngược lại, nếu (a[i] != x) di chuyển sang phần tử tiếp theo trong danh sách và sang
bước 3.
Bước 3: Tăng biên i lên 1: i = i+1;  xét phần tử tiếp theo trong mảng
Nếu (i == n) với n là số phần tử trong mảng thì  hết mảng, không tìm thấy phần tử x
trong danh sách. Dừng và quay lại bước 2

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
}

 Nhận xét về thuật toán:


Giải thuật tìm kiếm tuyến tính không phụ thuộc vào thứ tự tăng dần hay giảm dần của các
phần tử trong mảng.
Số phép so sánh của giải thuật trong trường hợp xấu nhất là 2n + 1.
Để giảm thiểu số phép so sánh trong vòng lặp cho giải thuật chỉ còn n + 1, có thể thêm
phần tử “lính canh” vào cuối dây như sau:
// Hàm tìm kiếm tuần tự với phần tử lính canh
int linearSearch(ItemType a[], int n, ItemType x)
{
int i = 0;
// Thêm giá trị cần tìm vào cuối mảng
a[n] = x;// a[n] là phần tử lính canh
while (a[i] != x)
i++;
// Nếu phần tử tại chỉ số i không phải là phần tử cần tìm
if (i < n)
return i; // Trả về vị trí của phần tử nếu tìm thấy
else
return -1; // Trả về -1 nếu không tìm thấy phần tử
}

2) Phương pháp tìm kiếm nhị phân (Binary)


Giải thuật
Giả sử ta có dãy chứa các giá trị đã được sắp xếp tăng (có thứ tự tăng theo một tiêu
chuẩn nào đó), các phần tử trong dãy có quan hệ ai-1 ≤ a ≤ ai+1, từ đó kết luận được
nếu x > ai thì x chỉ có thể xuất hiện trong đoạn [ai + 1, an] của dãy, ngược lại nếu x <
ai thì x chỉ có thể xuất hiện trong đoạn [ao, ai-1] của dãy. Giải thuật tìm nhị phân áp
dụng nhận xét trên đây để tìm các giới hạn phạm vi tìm kiếm sau mỗi lần so sánh x
với một phần tử trong dãy.
 Các bước tiến hành giải thuật
Gọi x là khóa cần tìm, a là mảng chứa các giá trị dữ liệu gồm n phần tử đã sắp xếp,
Left và Right là chỉ số đầu và cuối của đoạn cần tìm, Mid là chỉ số của phần tử nằm
giữa của đoạn cần tìm. Công việc tìm kiếm được tiến hành như sau:

- 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

Lần 1: Left =0, Right =7, Mid =3

x=14
7
1 2 5 9 10 14 30

Lần 2: Left =4, Right =7, Mid =5

x=14

1 2 5 7 9 10 14 30

Lần 3: Left =6, Right =7, Mid =6

x=14

1 2 5 7 9 10 14 30

Lần 4: Dừng

#code giải thuật


 Hàm không đệ quy
int BinarySearch(int a[], int n, int x)
{
int Left = 0; // Chỉ số bắt đầu của mảng
int Right = n - 1; // Chỉ số kết thúc của mảng

while (Left <= Right) {


int Mid = (Left + Right) / 2; // 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 phần tử được tìm thấy
else if (x < a[Mid])
Right = Mid - 1; // Di chuyển phạm vi tìm kiếm sang bên trái
else
Left = Mid + 1; // Di chuyển phạm vi tìm kiếm sang bên phải
}
return -1; // Trả về -1 nếu không tìm thấy phần tử
}

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.

You might also like