Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (159.17 KB, 15 trang )
Giả sử R là mảng gồm n bản ghi, bản ghi thứ k có một khóa X(k), với k=1,2...,n. Hãy
tìm bản ghi có khóa bằng (hoặc bé hơn, lớn hơn) giá trị b cho trước.
Giá trị b được gọi là khóa tìm kiếm hay đối trị tìm kiếm. Bài toán được gọi là giải
xong nếu như tìm được bản ghi thứ k nào đó mà X(k) = b hoặc khẳng định được rằng
không có bản ghi nào thỏa mãn điều kiện đặt ra, tức là X(k) b với mọi k=1,2,...,n.
4.1.Tìm kiếm tuần tự (Sequential Searching)
Ý tưởng
Bắt đầu từ bản ghi thứ nhất (k=1), lần lượt so sánh khóa tìm kiếm b với khóa tương
ứng của các bản ghi trong mảng, cho tới khi hoặc là tìm được bản ghi thỏa mãn điều kiện
hoặc là hết mảng mà không thấy.
Thuật toán
Input: Mảng X[1..n], giá trị b
Output: Chỉ số k [1..n] mà tại đó X(k)=b hoặc 0 nếu X(k) b với k [1..n]
Function TKTT (X: mảng; b: Khóa tìm kiếm): Chỉ số;
Begin
k:=1;
While (X(k) b & (k
n) do k:=k+1;
If k=n+1 then TKTT:=0 else TKTT:=k;
End;
Đánh giá thuật toán
Trong trường hợp xấu nhất ta cần 2n phép so sánh. Tuy nhiên nếu ta thực hiện một
cải tiến nhỏ như sau:
Input: Mảng X[1..n+1], giá trị b
Output: Chỉ số k [1..n] mà tại đó X(k)=b hoặc 0 nếu X(k) b với k [1..n]
Function TKTT (X: mảng; b: Khóa tìm kiếm): Chỉ số;
Begin
9
X(n+1)=b; k:=1;
While X(k) b do k:=k+1;
If k=n+1 then TKTT:=0 else TKTT:=k;
End;
Thì trong trường hợp xấu nhất ta cần n+1 phép so sánh. Trong cả hai trường hợp ta
có độ phức tạp của thuật toán là O(n).
4.2. Tìm kiếm nhị phân
Ý tưởng
Trên các bản ghi mà khóa đã được sắp xếp tăng dần so sánh khóa tìm kiếm b với
khóa của bản ghi ở giữa của đoạn mảng đang xét. Chẳng hạn mảng đang xét là X[l..r] thì
phần tử (bản ghi) ở giữa là X(k) với k=(l+r)/2; nếu X(k)=b thì việc tìm kiếm kết thúc, nếu
X(k)
hợp X(k)>b thì việc tìm kiếm sẽ được thực hiện trên mảng con X[k+1,r]. Quá trình tìm
kiếm trên mảng con sẽ được tiếp tục với thủ tục nêu trên.
Thuật toán
Input: Mảng X[1..n], giá trị b
Output: Chỉ số k [1..n] mà tại đó X(k)=b hoặc nếu X(k) b với k [1..n]
Function TKNP (b: Khóa tìm kiếm): Chỉ số;
Begin
TKNP:=0;
can_trai:=1; can_phai:=n;
While can_trai
can_phai do
Begin
K:=(can_trai + can+phai)/2;
If X(k) = b then
TKNP:=k;
Exit_loop;
Else If b< X(k) then can_phai:= k-1
Else can_trai:= k+1;
End
End;
Đánh giá thuật toán
10
Ta sẽ đánh giá vòng lặp mà thuật toán phải thực hiện. Giả sử n=2 d. Trong trường
hợp xấu nhất thuật toán thực hiện tới d vòng lặp. Mỗi vòng lặp có thể có tới 3 phép so
sánh. Như vậy số tối đa phép so sánh mà thuật toán phải thực hiện là 3d hay 3[log 2n]+3
với n tùy ý. Vậy độ phức tạp của thuật toán là O(log2n).
4.3. Tìm kiếm dựa trên quy hoạch động
Bài toán Dãy con dài nhất
Bài toán:
Cho dãy có n số S={X(1), X(2,....,X(n)}. Hãy tìm dãy con đơn điệu tăng (không giảm)
S’={X(p1), X(p2), ..., X(pn)}, với p1< p2<....< pk, có nhiều phần tử nhất, có nghĩa là k lớn
nhất.
Thuật toán:
1. Procedure Gán nhãn
{Kí hiệu L(i) – nhãn của X(i)}
1) L(1):= 1;
2) For i:=2 to n do
If (tồn tại X(j) với j
L(i):= max {L(j)+1:X(j)< X(i), j=1,2,..., i-1}
Else L(i):= 1;
PHẦN III: BÀI TOÁN ÁP DỤNG
1. Phát biểu bài toán
Cho dãy X gồm n số nguyên n ≤ 1000000. Hãy tìm dãy con đơn điệu gồm các
phần tử liên tiếp của X sao cho có nhiều phần tử nhất. Ví dụ, nếu X = { 12, 2, 3, 4, 6, 7, 1,
9, 10 } thì dãy con cần tìm là {2, 3, 4, 6, 7} có 5 phần tử.
2. Nhận định ban đầu
-
Số dãy con của x:
Chúng ta có thể xem mỗi dãy con x của X tương đương với một chuỗi nhị phân b,
độ dài n trong đó, bi = 0 nghĩa là ai không thuộc a và ngược lại bi = 1 nghĩa là ai thuộc a.
11
Ví dụ nếu X = [1, 3, 2, 3] thì dãy con tương ứng với chuỗi nhị phân b = 1010 là [1, 3].
Như vậy, số dãy con của X cũng chính là số chuỗi nhị phân có độ dài n chính là 2 n. Mặc
dù có thể với 2 chuỗi nhị phân khác nhau sẽ tương ứng với cùng một dãy con (với
mảng X = [1, 3, 2, 3], hai chuỗi 1100 và 1001 cùng tương ứng với dãy con [1, 3]), nhưng
nếu lập trình bình thường để duyệt tất cả các dãy con của X thì phải duyệt 2 n phần tử.
Với n = 100 thì có đến 2100≈ 1030 dãy con.
-
Phương án khả thi:
Phương án duyệt tất cả các dãy con để tìm kết quả tối ưu có độ phức tạp là O (2 n),
rõ ràng là không khả thi khi n lớn. Do đó chúng ta sẽ sử dụng thuật toán quy hoạch động
để giải bài toán.
3. Ý tưởng
- Đầu tiên xét for (int i=1; i
- Kiểm tra nếu a[i - 1] < = a [i] thì dãy tăng, ta thực hiện
{
maxT=lt[i-1]+1;
}
lt[i] = maxT;
if(maxT > maxTang)
{
maxTang = maxT;
}
Nếu a[i ] < = a [i - 1] thì dãy giảm, ta thực hiện
{
maxG=lg[i-1]+1;
}
lg[i]=maxG;
12