Tải bản đầy đủ (.doc) (11 trang)

Thuật toán tìm kiếm nhị phân

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 (78.43 KB, 11 trang )

Tìm Kiếm Nhị Phân
Vũ Anh Quân
Thuật toán tìm nhị phân hay còn gọi là phương pháp chia đôi được ápdụng rất nhiều trong
tin học. Phương pháp này làm giảm được nhiều thời gian tìmkiếm, giúp chương trình chạy
nhanh hơn. Sau đây tôi xin giới thiệu một số bàitoán sử dụng phương pháp trên.
Bàitoán 1: Xác định vị trí của phần tử X trong bảng liệt kê sắpxếp tăng các phần tử phân
biệt A
1
, A
2
,.., A
N
.(A
1
< A
2
<... < A
N
)
Bài giải: Chia đôi bảng liệt kê A
1
, A
2
,.., A
N
thành 2 bảng liệt kê:
A
1
, A
2
,.., A


m
và A
m+1
,A
m+2
,.., A
N
(trong đó m=(N+1) div 2).
+Nếu X>A
m
thìtìm kiếm trên bảng liệt kê A
m+1
, A
m+2
,.., A
N
.
+Nếu X<=A
m
thìtìm kiếm trên bảng liệt kê A
1
, A
2
,.., A
m
.
Quá trình trên được thực hiện cho tới khi bảng liệt kêchỉ còn một phần tử. Sau đó so sánh
X với số hạng này.
Mô tả thuật toán tìm kiếm nhị phân.
Function VT(X: integer): integer ;

Var
i, j, m : integer;
Begin
i:=1; j:=N;
while i<>
begin
m:= (i+j) div 2;
if X>A[m] then i:=m+1 else i:=m;
end;
if x=A[i] then VT:=i else VT:=0;
End;
Bài toán 2:
Có N thành phố, cho biết mỗi con đường nối từ thành phố bất kìi đến thành phố bất kì j
(với i khác j) có thể cho xe với trọng tải không quáC[i,j] đi qua. Cho thành phố xuất phát x
và thành phố đích y. Hãy tìm một đườngđi từ thành phố x tới thành phố y mà trọng tải lớn
nhất có thể được.
Dữ liệu vàotrong file Thanhpho.inp có dạng
Dòng đầu gồm 3 số N,x,y (N ≤ 100)
N dòng sau mỗi dòng N số nguyên không âm thể hiện matrận C[i,j]
(C[i,j]kiểu Integer)
Kết quả ra file Thanhpho.out có dạng
- Dòng đầu làtrọng tải lớn nhất có thể đi được từ x tới y.
- Dòng hai làdãy các thành phố từ x tới y.
Ví dụ:
Thanhpho.inp Thanhpho.out
4 1 4
0 2 1 1
1 0 2 1
1 1 0 2
1 1 1 2

2
1 2 3 4
Bài giải:
C
max
=MAX{C
ij
} với mọi i khác j; C
min
=0;
Kết quả bài toán sẽ nằm trong đoạn [ C
min
, C
max
].
Đặt C
tg
= (C
max
+C
min
)div 2.
Ta sẽ thử xem xe có trọng tải C
tg
có thể tồntại đường đi từ x tới y hay không? Dùng thuật
toán tìm kiếm theo chiều sâu(hoặc tìm kiếm theo chiều rộng) để xác định đường đi từ x tới
y. Chú ý rằng nếuC
tg
≤ C[i,j] thì có thể đi được từ thành phố i sang thành phố j.
Nếu tồn tại đường đi ta sẽ tìm kiếm tiếp trong đoạn [C

tg
+1,C
max
],và lưu kết quả này.
Nếu không tồn tại đường đi ta sẽ tìm kiếm tiếp trongđoạn [C
min
,C
tg
-1].
Cứ tiếp tục tìm kiếm cho tới khi đoạn có điểm đầu lớnhơn điểm cuối.
Chương trình thể hiện thuật toán trên như sau:
{$A+, B-, D+, E+, F-, G-, I+, L+, N-, O-, P-, Q+, R+,S+, T-, V+, X+}
{$M 16384, 0, 655360}
uses crt;
const
max = 100;
fi = 'thanhpho.inp';
fo = 'thanhpho.out';
var
c : array[1..max,1..max] of integer;
dx,kq, lkq : array[1..max] ofinteger;
cmin, cmax, ctg, ckq: word;
n, x, y, dem, ldem : integer;
ok : boolean;
procedure docf;
var
f : text;
i, j : integer;
begin
cmin:= 0; cmax:= 0;

assign(f,fi);
reset(f);
readln(f,n,x,y);
for i:=1 to n do
for j:=1 to n do
begin
read (f, c[i,j]);
if c[i,j]>cmax then cmax:=c[i,j];
end;
close(f);
end;
procedure ghinhan;
begin
ckq:= ctg;
ldem:= dem;
lkq:= kq;
ok:= true;
end;
procedure di(i: integer);
var
j: integer;
begin
if ok then exit;
for j:=1 to n do
if (dx[j]=0) and (c[i,j]>=ctg) then
begin
dx[j]:=1;
inc(dem);
kq[dem]:=j;
if j=y then ghinhan

else di(j);
if ok then exit;
dec(dem);
end;
end;
procedure lam;
begin
while cmin<=cmax do
begin
ctg:= (cmin+cmax) div 2;
fillchar(dx,sizeof(dx),0);
dem:=1; kq[1]:=x;
ok:= false;
di(x);

×