Tải bản đầy đủ (.pdf) (56 trang)

Đề cương cấu trúc dữ liệu và giải thuật

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 (437.47 KB, 56 trang )

Tr

ng HSP Thái Nguyên

Néi dung «n thi tèt nghiÖp
Môn :
Ngành:

C u trúc d li u và gi i thu t
S ph m Tin-K39

I-Quan h :
1. Quan h và bi u di n quan h .
2. Quan h ng c và quan h h p thành.
3. Quan h t ng
ng
4. Bao óng b c c u c a quan h
5. Thu t toán xây d ng bao óng b c c u c a quan h .
II-Phân tích và thi t k thu t toán.
1. Khái ni m thu t toán.
2. Thi t k thu t toán: Các chi n l c chia tr , thi t k t trên xu ng,
thi t k t d i lên và tinh ch nh t ng b c.
3. Phân tích thi t k thu t toán:
ph c t p c a thu t toán, xác nh
ph c t p c a tho t toán t t nh t, trung bình, x u nh t.
4. M t s các bài toán có
ph c t p a th c, hàm m , v n h b c
ph c t p c a 1 bài toán.
III- quy và thu t toán
quy:
1. Khái ni m v


quy, thu t toán quy
2. Thi t k thu t toán quy, ng d ng c a thu t toán quy.
3. Thu t toán quay lui và ng d ng
IV-Danh sách liên k t
1. Danh sách liên k t n: Khái ni m , cài t danh sách liên k t n.Các
phép toán x lý, ng d ng
2. Danh sách liên k t kép, danh sách n i vòng: Cài t các danh sách liên
t, các phép toán x lý v i m i lo i danh sách ó.
3. Stack và queue liên k t : Khái ni m các cách bi u di n, các phép toán x
lý, ng d ng.
V-S p x p và tìm ki m
1. Các ph ng pháp s p x p n gi n( l a ch n, chèn, n i b t): Ý t ng
a ph ng pháp.VD minh h a thu t toán, ánh giá
ph c t p c a th ât
toán.
2. Các ph ng pháp s p x p hi n i: (Phân
n, vung ng, hoà nh p):
Ý t ng, VD minh ho thu t toán,
ph c t p c a thu t toán.
3. Tìm ki m tu n t , nh phân: Ph ng pháp thuât toán, ánh giá
ph c
p c a thu t toán.


VI-Cây
1. nh ngh a và các khái ni m
2. Cây t ng quát: Các ph ng pháp bi u di n cây nh phân trên máy tính,
các phép duy t cây, các phép x lý cây tìm ki m nh phân.
3. ng ng a cây.
VIIth

1.
nh ngh a và các khái ni m bi u di n th
2. Chu trình Euler, thu t toán tìm chu trình và
ng i Euler
3. Chu trình Haminton và
ng i Haminton.
4. Duy t
th , tìm ki m theo chi u sâu, tìm ki m theo chi u r ng
5. Cây khung và cây khung v i giá tr c c ti u, thu t toán Kruskal
6. Bài toán bao óng truy n ng, s p x p topo và ng d ng.
7.
ng i ng n nh t, thu t toán Dijstra, thu t toán floyd.

Tr n

c Nam

2


C

NG C U TRC D

LI U V GI I THU T

I-Quan hệ:
1.Quan hệ và biểu diễn quan hệ:
a)Định nghĩa: Cho 2 tập A và B , tích đề các A và B
AxB= {(a,b)/ a A ,b B} phân biệt thứ tự. Một tập con R AxB gọi

là quan hệ trên A và B.
-Nếu B A thì ta nói R là một quan hên trên A, và R AxA.
VD: Cho hai tâp hợp: A={ a, b, c} ;B= { 1, 2}.
AxB= {(a,1), (a,2), (b,1), (b,2), (c,1), (c,2)}
R= {(a,1), (b,2), (c,2)} AxB
-Khi (a, b) R thì ta nói aRb (hay a có quan hệ R với b)
-Khi (a, b) R a không có quan hệ R với b.
b)Biểu diễn quan hệ:Quan hệ R AxB ta có thể biểu diễn quan hệ bằng
các cách sau:
-Liệt kê: Liệt kê mọi phần tử của R.
-Xác định một tính chất:
VD: A={1, 2, 3, 4, 5, 6}
R={(a,b) | a, bA: a-b= 2k, kZ}
-Ph-ơng pháp đồ thị: R AxA. A={a11, a21,...,an} ta t-ơng ứng mỗi
phần tử của R với mỗi đỉnh của đồ thị.
-Ph-ơng pháp ma trận quan hệ:
R= AxB,
A={a11, a21,...,am}
B={b11, b21,...,bn}
+ Ta dựng ma trận: MR=(mij)nxm
mij= 1 nếu ai R bj ,
mij = 0 Neu

ai Rbi

c)Một số tính chất của quan hệ: Xét R AxA có những tính chất sau:
(1) .Phản xa : a A : a R a
(2)
.Đối xứng: (a, b) R, (b, a ) R . aRb bRa
aRb

a=b
bR a

(3) .Phản xứng: a,b A .Ta có:

aRb
bRc

(4) .Bắc cầu: a,b A.Ta có:

aRc.

2.Quan hệ ng-ợc và quan hệ hợp thành.(Ch-a bit)

Tr n

c Nam

3


3.Quan hệ t-ơng đ-ơng:
-R AxA đ-ợc gọi là quan hệ t-ơng đ-ơng trên A nếu nó có các tính
chất:
+Phản xạ: a A : aRa
(a, b) R
aRb bRa
(b , a ) R
aR b
+Bắc cầu:

=> aRc
bR c

+Đối xứng:

-Phân hoạch t-ơng đ-ơng của 1 tập hợp: Một hệ thống các tập con A1,
A2 Ak A.Có tính chất: Ai I Aj = i j và A1 U A2 U Ak đ-ợc
gọi là một phân hoạch t-ơng đ-ơng trên tập A.
4.Quan hệ bao đóng bắc cầu:
-Giả sử R là quan hệ trên A, R có thể có tích chất bắc cầu hoặc không
chứa R. S là quan hệ bắc cầu, R S.
-Quan hệ bắc cầu nhỏ nhất trên A chứa R đ-ợc gọi là bao đóng bắc
cầu cảu quan hệ R.Ký hiệu [ R ]
Nhân xét:+ Nếu bản thân R có tính chất bắc cầu thì bao đóng bắc cầu
trùng R không thì phải thêm 1 vài phần tử nữa vào tập R để trở thành bắc
cầu.
VD:
A={a, b, c}, R={(a,b), (b,c)}
[ R ] ={(a,b), (b,c), (a,c)}
+Bao đóng bắc cầu còn đ-ợc gọi là bao đóng truyền ứng
5.Thuật toán xây dựng bao đóng bắc cầu.
-Ta lần l-ợt tìm các ma trận MR , rồi tính:
M R =M R = M R M R
2

1

2

M R3 = M R2 M R = M R3

M Rn = M Rn = M Rn1 M R
=> M [ R] = M R1
*)Cộng bít: ( )
1 1 = 1
1 0 = 1
0 1 = 1
00 = 0

*)Nhân bit:( ):

M R2 ... M Rn

1 1 = 1
1 0 = 0
0 1 = 0

-Đặt biệt:

00 = 0

Tr n

c Nam

4

1=0
0 =1



*)Xét A và B : A=(aij); B=(bij) với kích th-ớc :
A B = (aij bij ) : Lấy các phần tử t-ơng ứng cộng lại.
A B = (aij bij )
C = A B
C ij = a i1 b1 j a i 2 b2 j ... a in bnj

*)Thuật toán:
Procedure Baodongbaccau(MR:Matran quan he R)
Begin

A := M R

B := A

For i:=2 to n do

Begin

A := A M R

B := B A
End;

End;

VD1: Cho A={a, b, c} và R={ (a,a), (a,c), (b.b), (c,a), (c,b)}
Dùng thuật toán trên tìm bao đóng bắc cầu:R
1 1 1
1 0 1
1 1 1


M = 0 1 0


M R= 0 1 0 R 2
; M R = 0 1 0 = M [ R]
1 1 1
1 1 0
1 1 1






VD2: Cho A={1, 2, 3, 4, 5, 6}
R= {(a,b)/ a, b A: a-b=3k, kZ}
1)Chỉ ra R là t-ơng đ-ơng?
2)Tìm phân hoạch t-ơng đ-ơng?
Giải:
1)R là t-ơng đ-ơng vì:
+R có tính phản xạ:aA: a-a=3kú 0=3k =>k= 0,k Z
+R có tính đối xứng:a, b A: a-b=3k=>b-a= -3k (kZ)
+R có tính bắc cầu : a, b, c A:
3

a b = 3k1
(k1 , k2 Z ) a c = 3(k1 + k 2 ) =3k (kZ)

b c = 3k2


-Theo định nghĩa quan hệ t-ơng đ-ơng điều đó chứng tỏ rằng quan hệ

R là một quan hệ t-ơng đ-ơng trên tập A.
2)Tìm phân hoạch t-ơng đ-ơng:

Tr n

c Nam

5






MR=





1 0 0 1 0 0
0 1 0 0 1 0
0 0 1 0 0 1
=> Tập phân hoạch t-ơng đ-ơng là:
1 0 0 1 0 0
0 1 0 0 1 0


0 0 1 0 0 1

A1= {1, 4}, A2={3, 6}, A3= {2, 5}
II-Phân tích và thiết kế thuật toán
1.Khái niệm về thuật toán: Thuật toán là một dãy hữu hạn các b-ớc, mỗi
b-ớc mô tả chính xác các thao tac cần đ-ợc thực hiện để giải quyết bài
toán.Và sau hữu hạn các b-ớc đó, từ input của bài toán ta đ-ợc output của
bài toán.
VD: Thuật toán tìm UCLN của 2 số nguyên d-ơng a và b
-Phân tích: Lặp r = a mod b
a=b; b=r;
Dừng r=0 ; (a,b)=a ;
-Thuật toán: +B1: Input: a,bZ+
Output: UCLN(a,b)
+B2: a= b ; b = r;
+B3: Nếu r=0 thì UCLN(a,b)=a
Nếu r 0 thì quay về B1.
2.Thiết kế thuật toán:
-Các bài toán phức tạp và đa dạng việc giải quyết trên ma trận là rất khó
khăn.Tuy nhiên đối với những bài toán lớn hay bài toán phức tạp thì ta có thể
phân chia bài toán lớn thành các bài toán nhỏ hơn(modul ch-ơng trình nhỏ
hơn). Ta lại có thể chia các bài toán nhỏ thành các modul nhỏ ứng với các
phần việc cơ bản mà ta đã biết cách giảI quyết, nh- vậy việc tổ chức lời giải
Của bài toán sẽ đ-ợc thực hiện theo một cấu trúc phân cấp nh- sau:
A
B

E

C


F

G

D

H

I

Chiến thuật giải quyết bài toán theo tinh thần nh- vậy chính là chiến thuật
Chia để trị ->Để thực hiện đ-ợc chiến thuật này ng-ời ta dùng cách thiết
kế từ trên xuống <top-down> hoặc có thể sử dụng ph-ơng pháp từ d-ới
lên(Up-down).
Tr n

c Nam

6


a)Chiến l-ợc thiết kế thuật toán từ trên xuống:
-Nếu quá trình từng b-ớc triển khai và chi tiết hoá ch-ơng trình ngày càng
đi vào chiều sâu thì ph-ơng pháp giải bài toán đ-ợc gọi là từ trên xuống.
*)ý t-ởng: Giả sử ta giải quyết 1 bài toán lớn T thì khi đó ta sẽ chia bài toán
T thành các bài toán con. Nếu các bài toán con này ch-a có thuật giải thì ta
lại cỏ thể chia các bài toán con này thành các modul nhỏ ứng với các phần
việc cơ bản mà ta đã biết cách giải quyểt.
-Thiết kế giải thuật top-down là việc giải quyyết bài toán đ-ợc định h-ớng rõ

ràng tránh đ-ợc việc xa đà vào các chi tiết phụ quản lý đối t-ợng rõ ràng.Đây
là nền tảng của lập trình có cấu trúc hay còn gọi là h-ớng thủ tục.Bài toán
đ-ợc chia thành nhiều modul t-ơng đối độc lập nhiều ng-ời tham gia giải
quyết và ít ảnh h-ởng lẫn nhau đối với giải thuật phức tạp.
- Ph-ơng pháp này còn hạn chế nh- quản lý độ phức tạp, quản lý và phát
triển hệ thống.
b)Chiến l-ợc thiết kế thuật toán từ d-ới lên:
-Ph-ơng pháp đi đến lời gíải bài toán, trong đó ng-ời lập trình tr-ớc hết
nghiên cứu ngôn ngữ lập trình sẵn có rồi kết hợp những chỉ thị thành những
thủ tục hoặc hàm đơn giản hoặc thành những nhóm tiêu biểu cho bài toán
cần giải. Sau đó các thủ tục, hàm này đ-ợc sử dụng ở các thủ tục hay hàm
cấp cao hơn.Ph-ơng pháp đó đ-ợc gọi là từ d-ới lên ( từ d-ới độ sâu của các
lệnh máy nguyên thuỷ đến bài toán trên cao )
*)ý t-ởng: Để giải một bài toán nào đó, ta cần chọn ra trong số các ch-ơng
trình đã biết, một số modul( đoạn ch-ơng trình con). Mỗi modul sẽ thực hiện
một số chức năng nhất định.Việc chọn các modul đ-ơc xác định bởi những
suy nghĩ khác nhau: Sự dễ hiểu của các chức năng mà mỗi modul cần thực
hiện, kích th-ớc đoạn ch-ơng trình, cấu trúc dữ diệu, sự giống nhau có thể có
với những công việc mới và khả năng chuyển cho những ,modul đã biết ấy
những nhiệm vụ mới Mỗi modul cần xác định những mối liên hệ giữa dữ
liệu vào và những dữ liệu ra. Việc lập trình và kiểm thử đ-ợc tiến hành theo
những modul ấy. Sau đó các modul đ-ợc hợp nhật vào các đơn vi lớn hơn
trên cơ sở những mối liên hệ đã định tr-ớc. Các đơn vị này lại đ-ợc kiểm thử,
sửa chữa các thiếu sót, các bất hợp lý có thể xuất hiện trong quá trình hợp
nhất...cuối cùng các đã có lại đ-ợc hợp nhất trong ch-ong trình chung để giải
quyết bài toán đặt ra.
-Một ứng dụng hay dùng nhất của kỹ thuật này là sửa chữa những ch-ơng
trình, những đoạn ch-ơng trình, những ch-ơng trình con đã có của một lời
giải bài toán nào đó đã biết để đ-ợc ch-ơng trình giải bài toán mới.
c)Tinh chỉnh từng b-ớc, làm mịn dần.

-Tinh chỉnh từng b-ớc là ph-ơng pháp thiết kế thuật giải găn liền với lập
trình. Nó phản ánh tinh thần của quá trình modul hoá bài toán và thiết kế
kiểu top-down.Thoạt đầu ch-ơng trình thể hiện giải thuật đ-ợc trình bày
Tr n

c Nam

7


bằng ngôn ngữ tự nhiên phản ánh ý chính của công việc cần làm.Càng ở các
b-ớc sau các lời lẽ đặc tả công việc xử lý sẽ đ-ợc thay thế dần bởi các câu
lệnh h-ớng tới các lệnh của ngôn ngữ lập trình, ta gọi đó là các b-ớc tinh
chỉnh. Nh- vậy nghĩa là quá trình thiết kế giải thuật và phát triển ch-ơng
trình sẽ đ-ợc thể hiện dần dần từ dạng ngôn ngữ tự nhiên, qua giả ngôn ngữ
rồi đến ngôn ngữ lập trình và đi từ mức làm cái gì đến mức làm thế nào ,
ngày càng sát với các chức năng với các câu lệnh của ngôn ngữ lập trình đã
chọn.
- Trong quá trình xây dựng thuật giải, ban đầu thuật giải đ-ợc viết d-ới dạng
dễ nhận biết.Theo thuật giải này, ở những b-ớc nào đó sẽ gặp khó khăn khi
mã hoá, hoặc là ch-ơng trình chạy sẽ mất nhiều thời gian có khi vi phạm đến
tính hiệu quả của thuật giải, thì ta tìm cách cải tiến, chi tiết hoá ở những
b-ớc đó.Ta có thể chi tiết thêm hoặc là cải tiến để thuật giải tốt hơn, số thao
tác mà máy thực hiện ít đi hoặc tiết kiệm bộ nhớ khi l-u trữ dữ liệu. Ta bám
theo quá trình máy tính thực hiện ch-ơng chình để thấy đ-ợc những chỗ bất
hợp lý hoặc không cần thiết mà điều chỉnh thuật giải cho tốt hơn.
3.Phân tích thuật toán:
a)Độ phức tạp của thuật toán:
-Khi nói đến độ phức tạp của thuật toán ng-ời ta th-ờng đề cập đến độ phức
tạp về thời gian và độ phức tạp về dung l-ợng nhớ.

-Khi thiết kế thuật toán th-ờng ta dung hoà 2 tiêu chí ở trên theo nghĩa thuật
toán vừa chạy nhanh vừa tốn ít bộ nhớ. Tuy nhiên ng-ời ta th-ờng đề cập tới
độ phức tạp về thời gian.
- Thời gian thực hiện thuật toán phụ thuộc vào nhiều yếu tố: Trình độ ng-ời
lập trình, đặc điểm dữ liệu vào, phần cứng, ngôn ngữ lập trình
*)Định nghĩa: Một hàm f(n) đ-ợc xác định là O(g(n))
f(n)=O(g(n)) và đ-ợc gọi là có cấp g(n) nếu tồn tại các hằng số c và n0
sao cho: f(n) cg(n) khi n n0. Nghĩa là f(n) bị chặn trên bởi 1 hằng số nhân
với g(n), giá trị của n từ 1 điểm nào đó.Ki hiệu:T(n)
VD: Cho hàm : T(n)= n2+3n+2.Suy ra:
T(n)= n2+3n+2 n2+3n2+2n2
T(n) 6n2 n 1.
T(n)=O(n2). Độ phức tạp bình ph-ơng(f(n)=n2, c=6, n0=1)
b) Các quy tắc đánh giá độ phức tạp của thuật toán:
-Để đánh giá độ phức tạp của thuật toán ng-ời ta sử dụng 2 quy tắc: Quy tắc
cộng và quy tắc nhân.
*)Quy tắc cộng: Giả sử có 2 đoạn ch-ơng trình P1 và P2 thực hiện tuần tự, và
có độ phức tạp t-ớng ứng lần luợt là: T1(n)= O(f(n))
T2(n)= O(g(n)
Khi đó độ phức tạp của đoạn ch-ơng trình bao gồm P1 và P2 sẽ là:
T(n)= O(max(f(n), g(n)))
Tr n

c Nam

8


VD: Nếu g(n) f(n) n n0 O(f(n)+ g(n))= O(f(n).
Chẳng hạn: O(n4 +n2)= O(n4)

O(n +nlog2n)= O(n)
*)Quy tắc nhân: Giả sử có 2 đoạn ch-ơng trình P1, P2 thực hiẹn lồng nhau,
có độ phức tạp lần l-ợt là:T1(n)= O(f(n))
T2(n)= O(g(n))
Khi đó độ phức tạp của đoạn ch-ơng trình gồm cả P1, P2 là:
T(n)= O(f(n).g(n))
+VD: for i:= 1 to n do
for j:=1 to n do x:= x+1
Thời gian thực hiện thuật toán là: O(n.n)= O(n2)
-Ng-ời ta đánh giá độ phức tạp của thuật toán trong 3 tr-ờng hợp:
Tốt nhât (Tmin(n)), xấu nhất (Tmax(n)), trung bình (TTB(n)).Khi phân tích thời
gian thực hiện giải thuật ta sẽ phải xét tới: đối với mọi dữ liệu vào có kicks
th-ớc n thì T(n) trong tr-ờng hợp thuận lợi tốt nhất là nh- thế nào? Rồi T(n)
trong tr-ờng hợp xấu nhất? Và T(n) trung bình?Nh-ng ng-ời ta th-ờng đánh
giá giải thuật qua giá trị xấu nhất của T(n), khi mà trong tr-ờng hợp T(n)
trung bình khó xác định.
c) M t s cỏc bi toỏn cú
ph c t p a th c, hm m , v n h b c
ph c t p c a 1 bi toỏn:
-Thông th-òng ta chia bài toán thành 3 lớp:
+1-Lớp bài toán giải đ-ợc có đọ phức tạp đa thức
+2-Lớp bài toán np đầy đủ
+3-Lớp bài toán giải đ-ợc bằng thuật toán có độ phức tạp hàm mũ
-Lớp bài toán (2) và (3) : Các bài toán bất khả thi, trong đó chúng khó có thể
thực hiện trên máy tính điện tử do thời gian thực hiện quá lớn.Khi đó ta cần
chia chúng thành các lớp con riêng biệt và đ-a các lớp con về lớp các bài
toán có độ phức tạp đa thức.
-Lớp bài bài toán có độ phức tạp đa thức, ta cố gắng giảm số mũ k xuống:
+Cấu trúc dữ liệu phù hợp
+Sử dụng ngôn ngữ lập trình gần ngôn ngữ máy.

*)Độ phức tạp của thuật toán th-ờng tiệm cận đến một trong các hàm sau
đây:
Dạng đánh giá
Tên gọi
O(1)
Hàm hằng
O(lglgn)
Log log
O(logn)
Logarithm
O(n)
Tuyến tính
O(nlogn)
Tuyến tính logarithm
2
O(n )
Bình ph-ơng

Tr n

c Nam

9


O(n3)
Lập ph-ơng
k
Đa thức
O(n ) k2

n
O(2 )
Hàm mũ
O(n!)
Giai thừa
Bảng -Cách đánh giá độ phức tạp thông dụng
Theo bảng trên độ phức tạp thuật toán đ-ợc liệt kê theo thứ tự tăng dần từ
trên xuống.
III-Đệ quy và thuật toán đệ quy:
1.Khái niệm về đệ quy, thuật toán đệ quy:
a)Khái niệm đệ quy: Ta nói một đối t-ợng là đệ quy nếu nó bao gồm chính
nó nh- một bộ phận hoặc nó đ-ợc định nghĩa d-ới dạng của chính nó.
*)VD: +Số tự nhiên :
a) 1 là số tự nhiên
b) x là số tự nhiên nếu x-1 là số tự nhiên
+ Hàm n giai thừa: n!
a)0!=1
b)Nếu n> 0 thì n!= n(n-1)!
b)Thuật toán đệ quy: Nếu lời giải cảu bài toán T đ-ợc thực hiện bởi bài toán
, có dạng nh- T thì đó là một lời giải đệ quy.Giải thuật chứa lời giả đệ quy
gọi là giải thuật đệ quy.
-Một thủ tục gọi là thủ tục đệ quy nếu trong thủ tục đó có lời gọi 1 cách trực
tiếp hay gián tiếp.
VD1: Dùng thủ tục hàm đệ quy f(n)=n!
Fuction GT(n:byte): Longint;
Begin
If n=0 then GT:=1
Else
GT:= n*GT(n-1);
End;


VD2: Hãy tính số hạng thứ n của dãy Fibonaci {1, 1, 2, 3, 5, 8, 13, 21, ....}
Function F(n: byte): Longint;
Begin
If n= 1 then F:= 1
Else
if n= 2 then F:=2
Else F:= F(n-1)+F(n-2);
End;
1+ 5
-Độ phức tạp :T(n)= O( n ) với =
2
VD3: Bài toán tháp Hà Nội:
A
B
N= 1: A B
(n 1) : A C

N> 1:
1: A B
(n 1) : C B


Tr n

c Nam

10

C



*)Thuật toán: Để chuyển n đĩa từ A sang C ta lấy B làm trung gian:
+Chuyển n-1 đĩa từ A sang B, lấy C làm trung gian.
+Đem 1 đĩa từ A sang C.
+ Chuyển n-1 đĩa từ B sang C, lấy A làm trung gian.
*)Thủ tục:
Program ChuyenDia(X, Y: cot);
Begin
Writeln( Chuyen mot dia tu ,X, sang ,Y,
End;
Procedure Doicot(n, A, B, C);
Begin
If n > 0 then
Begin
Doicot(n-1, A, C, B);
ChuyenDia(A,C) ;
Doicot(n-1, B, A, C);
End;
End;
n!
c)Tính đệ quy của ch-ơng trình:
n

);

(n-1)!
(n-1)

(n-2)!


1!
1

0!= 1

2. Thi t k thu t toỏn quy, ng d ng c a thu t toỏn quy.
-Khi bi toỏn ang xột ho c ang x lý
c nh ngh a d i d ng quy
thỡ vi c thi t k cỏc gi thu t quy t ra r t thu n l i. H u nh nú ph n
ỏnh r t sỏt n i dung c a nh ngh a ú.
-Chỳ ý: i v i 2 bi toỏn VD1 v VD2 trong m c 1b nờu trờn thỡ vi c
thi t k cỏc gi i thu t quy t ng ng khỏ thu n l i vỡ c hai u thu c
ng tớnh giỏ tr hm m nh ngh a quy c a hm ú xỏc nh
cd
dng. Nh ng khụng ph i lỳc no tớnh quy trong cỏch gi i bi toỏn c ng
th hi n rừ nột v n gi n nh v y. V y thỡ v n no c n l u tõm khi
thi t k m t gi i thu t quy? Cú th tr l i cõu h i qua vi c gi ỏp cỏc
cõu h i sau:
(2.1).Cú th nh ngh bi toỏn d i d ng m t bi toỏn cựng lo i,
nh ng nh h n, nh th no?
Tr n

c Nam

11


(2.2).Nh th nào là kích th c c a bài toán
c gi m i m i l n

i quy?
(2.3).Tr ng h p c bi t nào c a bài bài toán
c coi là tr ng h p
suy bi n.
3. Thu t toán quay lui và ng d ng
-Thu t toán quay lui dùng gi i bài toán li t kê các c u hình.M i c u
hình
c xây d ng b ng cách xây d ng t ng ph n t , m i m t ph n t
c ch n b ng cách th t t c các kh n ng.
Gi thi t c u hình c n li t kê có d ng (x1, x2,...,xn).Khi ó thu t toán quay
lui
c th c hi n qua các b c sau:
1)Xét t t c các giá tr x1 có th nh n, th cho x1 nh n l n l t các giá tr
ó. V i m i giá tr th gán cho x1 ta s :
2) Xét t t c các giá tr x2 có th nh n, l i th cho x2 nh n l n lu t các giá
tr ó. V i m i giá tr th gán cho x2 l i xét ti p kh n ng ch n x3,..c ti p
c nh v y n b c n:
.............................................
n) Xét t t c giá tr xn có th nh n, th cho xn nh n l n l t các giá tr ó.
Thông báo c u hình tìm
c (x1, x2,...,xn).
*)Mô hình c a thu t toán quay lui
c mô t nh sau:
{ th t c này cho x nh n l n l t các giá tr mà nó có th nh n}
Procedure Try(i: integer );
Begin
For (m i giá tr c a V có th gán cho xi) do
Begin
<Th cho xi: = V>;
If (xi là ph n t cu i cùng trong c u hình) then

< thông báo c u hình tìm
c>
Else begin
<ghi nh n vi c cho xi nh n giá tr V (n u c n) >;
Try(i+1); {ch n quy nh n ti p giá tr xi+1}
<N u n, b ghi nh n xi: = V th giá tr khác> ;
End;
End;
End;

-Thu t toán quay lui s b t u b ng l i gi i Try(1).
Ta có th trình bày b ng quá trình tìm ki m l i gi i c a thu t toán quay lui
ng cây sau:
Try(1)
Try(2)

Try(3)

Tr n

c Nam

Try(2)

Try(3)

Try(3)

12


Try(3)


Cây liệt kê lời giải theo thuật toán quay lui.
VD1. Liệt kê các dãy nhị phân độ dài n.
Giải :
Biểu diễn dãy nhị phân d-ới dạng b1, b2,...bn, trong đó bi {0, 1}. Thủ tục

đệ quy Try(i) xác định bi, trong đó các giá trị đề cử là 0 và 1.Các giá trị
này mặc nhiên đ-ợc chấp nhận mà không phải thoả mãn điều kiện gì (vì
thế bài toán không cần biến trạng thái). Thủ tục Init nhập giá trị n và
khởi gán biến đếm dem. Thủ tục Result đ-a ra dãy tìm đ-ợc.
{ Ch-ơng trình liệt kê dãy nhị phân}

Uses crt;
Var n: integer ;
b: array[1..20] of 0..1;
dem: word;
Procedure Init;
Begin
Write( n= ); readln(n);
dem:= 0;
end;
Procedure
Result;
Var i: integer;
Begin
Dem:= dem +1;
Write(dem:5,
);

For i:=1 to n do write(b[i]:2);
Writeln;
End;
Procedure Try(i: integer);
Var j: integer;
Begin
J:= 0 to 1 do
Begin
B[i]: = j;
If i = n then Result
Else
Try(i+1);
End;
End;
Begin
{main}
Init; Try(1);
Write( Go enter de ket thuc ) ; readln;
End.

VD2: Bài toán mã đi tuần
Đề bài:
Cho 1 bàn cờ có kích th-ớc n x n (n>=3)
Một con mã di chuyển theo luật cờ vua đ-ợc đặt trong 1 ô với toạ độ
đầu là (x1,y1). Hãy tìm 1 đ-ờng đi với n2 1 b-ớc đi sao cho mọi ô trên bàn
cờ đều đ-ợc mã nhảy đến đúng một lần

Tr n

c Nam


13


Xác định bài toán:
a. Input
- Một bảng vuông kích th-ớc n x n
- Toạ độ của vị trí thứ nhất của quân mã
- Tám n-ớc đi có thể của quân mã đ-ợc biểu diễn bởi hình sau :
X1
3
2
4
1
Y1
5
8
6
7
b.Output
- Một bảng vuông trên đó có đánh dấu vị trí theo thứ tự từ 1 (vị trí đầu) đến
n2 (vị trí cuối ) của quân mã.
- Từ vị trí k đến vị trí k +1 phải theo đúng luật đi của quân mã (nghĩa là chỉ
đ-ợc sử dụng 1 trong 8 n-ớc đi mô tả ở trên).
- Ví dụ: n=5, x1=1, y1=1
1 10 5 14 25
4 15 2 19 6
9 20 11 24 13
16 3 22 7 18
21 8 17 12 23

c. Xác định các thao tác chế biến thông tin:
- Lần l-ợt xác định các vị trí của quân mã (từ 2 đến n2) sao cho quân
mã :

*Di chuyển đúng luật.
*Mỗi ô chỉ đ-ợc đi 1 lần.
d. Thiết kế thuật toán
* Ta sẽ biểu diễn bàn cờ bằng 1 ma trận vuông cấp n
Sở dĩ thể hiện mỗi ô cờ bằng 1 số nguyên thay cho giá trị boole (để
đánh dấu
ô đã đ-ợc đi qua ch-a) là vì ta muốn lần dò theo quá trình di
chuyển của con
ngựa.
Ta quy -ớc nh- sau :
dd([x,y]) = 0 <x,y> ngựa ch-a đi qua
dd([x,y]) = 1 <x,y> ngựa đã đi qua ở b-ớc thứ i (1<=i<=n2)
*Các khả năng chọn lựa cho x1 ? Đó chính là các n-ớc đi của ngựa mà
xi có thể chấp nhận đ-ợc.
Với cặp toạ độ ban đầu <x,y> nh- trong h.vẽ, có tất cả 8 ô <u,v> mà
con ngựa có thể đến. Giả sử chúng đ-ợc đánh số từ 0 tới 7 nh- hình sau :

Tr n

c Nam

14


(-2,-1)


4

(-1,-2)

(1,-2)

5
Hàng

(a,b)

2
*

6

(2,-1)

Toạ độ

3
1

7
1

2

0
3


4

5

1
2
3
4
5
H
C

(-2,1)
(-1,2)

x

(1,2)
(2,1)
Toạ độ
(a,b)

cột y

Một ph-ơng pháp đơn giản để có đ-ợc u,v từ x,y là ta dùng 2 mảng a và b
l-u trữ các sai biệt về toạ độ. Nếu dùng 1 chỉ số k để đánh số b-ớc đi kế
thì chi tiết đó đ-ợc thể hiện bởi : u = x+a[k];v=y+b[k];k=1->8;
Điều kịên chấp nhận đ-ợc có thể đ-ợc biểu diễn nh- kết hợp của các điều
kiện :

Ô mới phải thuộc bàn cờ (1<=u<=n va 1<=v<=n) và ch-a đi qua ô đó,
nghĩa là dd([u,v]) = 0;
*Để ghi nhận n-ớc đi hợp lệ ở b-ớc i, ta gán dd([u,v]) = i; và để huỷ bỏ 1
n-ớc đi thì ta gán dd([u,v]) =0;
*Ma trận dd ghi nhận kết quả nghiệm. Nếu có <x,y> sao cho dd<x,y> = 0 thì
đó ko phải lời giải của b.toán, còn ng-ợc lại la dd chứa đ-ờng đi của ngựa.
*thuật toán nh- sau:

Program Madituan;
Uses crt;
Const
a:array[1..8] of integer=[2,1,-1,-2,-2,-1,1,2];
b:array[1..8] of integer=[1,2,2,1,-1,-2,-2,-1];
n=5;nsq=25;
Var
q:boolean;
dd:array[1..n,1..n] of integer;
s:set of 1..n;
x,y:integer;
Procedure Init;
Begin
Writeln( Cho biet toa do ban dau cua ngua );
Readln(x,y);
dd[x,y]:=1;
q:=false;
s:=[1,2,3,4,5];
End;
Procedure Print;
Var i,j:integer;
Begin

q:=true;
For i:=1 to n do
Begin

Tr n

c Nam

15


For j:=1 to n do
Write(dd[i,j]:5);
Writeln;
end;

end;
Procedure Try(i:integer);
Begin
If i>nsq then print
Else
For j:=1 to 8 do
Begin
u:=x+a[j];
v:=y+b[j];
If (u in s) and (v in s) and(dd[u,v] = 0) then
Begin
dd[u,v]:=i;
x:=u;
y:=v;

Try(i+1);
y:=v-b[j];
x:=u-a[j];
dd[u,v]:=0;
end;
end;
end;
Begin{Chuong trinh chinh}
Init;
Try(2);
If q=false then
Writeln( Vo nghiem );
Readln;
End.

IV-Danh sỏch liờn k t
1. Danh sỏch liờn k t n:
1.1)Khỏi ni m: L 1 tập hợp có thứ tự các phần tử cùng kiểu và có số l-ợng
biến động.Đối với danh sách ng-ời ta có một số thao tác: Tìm một phần tử
trong danh sách, chèn một phần tử trong danh sách, sắp xếp các phần tử
trong 1 danh sách theo một thứ tự nào đó
-Danh sách tuyến tính là danh sách trong đó 2 phần tử kề nhau có mối quan
hệ tuyến tính.
VD: Một hệ tuyến tính i, j. Kí hiệu: L= ( a1, a2 , an). Khi đó:
N= 0 danh sách rỗng
n> 0 : a1, an t-ơng ứng là phần tử đầu tiên, cuối cùng của danh sách
ai+1, ai-1 t-ơng ứng là phần tử đi tr-ớc ai và đi sau ai. n là độ dài danh sách.
1.2)Ci t danh sỏch liờn k t n.Cỏc phộp toỏn x lý, ng d ng
*)Khai bỏo d li u :
Type


Tr n

Pointer = ^Node;
Node = Record;

c Nam

16


End;

Info: Data;
Next: Pointer;
List= Pointer;

*)Khởi tạo danh sách liên kiết:
Danh sách rỗng
First= Nil.
Procedure InitList;
Begin
First: = Nil;
End;
*)Cỏc phộp toỏn x lý:
1.2.1)Tỡm ki m m t ph n t trong danh sỏch:Gi s c n tỡm ki m ph n t
cú tr ng thụng tin l x. Phộp tỡm ki m
c th c hi n t ph n t
u cho
n khi tỡm th y ph n t cú tr ng thụng ti x ho c n cu i danh sỏch (

khụng tỡm th y ).
-Hm Search tr v a ch c a ph n t
u tiờn ho c tr v giỏ tr Nil n u
khụng tỡm th y.
-T ng t nh
i v i danh sỏch c, phõn bi t hai tr ng h p:
Danh sỏch ch a
c s p x p. Phộp tỡm ki m ch k t thỳc khi tỡm
th y ph n t
u tiờn ho c h t danh sỏch:
Function Search(x:Data):Pointer;
Var
P: Pointer;
Found: Boolean;
Begin
Found:= false;
P:=First;
While (p<> Nil) And( Not Found) do
If p^.info= x then Found:= True
Else
p:= p^.Next ;
Search := p;
End:



Danh sỏch
c s p x p t ng d n: Ch c n tỡm cho n khi g p
ph n t
u tiờn ho c khoỏ c a ph n t hi n t i l n h n x.


Function

Search(x:Data):Pointer;
Var
P: Pointer;
Begin
P:=First;
While (p<> Nil) And( p^. info< x) do
P:= p^.next ;
If (p<> Nil)And(p^.info> x) then
p:= Nil;Search := p;End;

1.2.2)Thêm một phần tử vào danh sách-

Tr n

c Nam

17


-Đối với danh sách liên kết, việc thêm hoặc huỷ một phần tử khỏi danh
sách nhanh hơn so với danh sách đặc. Chỉ cần thay đổi vùng liên kết của
phần tử mằn ở vị trí cần thêm huỷ.
Thêm vào đầu danh sách: Gọi p là địa chỉ của phần tử có tr-ờng thông
tin NewItem mới đ-ợc thêm vào, khi đó First trở thành phần tử thứ 2
sau p. Nh- vậy ta cần thực hiện các b-ớc sau:
+ Cho vùng liên kết của p trỏ vào First.
+ Cho First trỏ vào p.

Dùng hàm:
Function InsertFirst(NewItem: Data): Pointer;
Var p: pointer;
Begin
New(p);
P^.info:= NewItem;
P^.Next:= First;{Buoc 1}
First:= p;
{Buoc 2}
InsertFirst:=p;
End;

Thủ tục:Chèn 1 nút mới info là x , và tr-ớc p.Chèn một nút mới vào sau nút
đ-ợc trỏ bởi P, hoán đổi tr-ờng thông tin.
Procedure InsertBefore(X:Data;Var L:List;P:Pointer);
Var Q: Pointer;
Begin
If L= Nil then Begin
Q^.info:= X;
Q^.Next:= Nil;
L:= Q;
End
Else Begin
New(P);
Q^.info:= x;
Q^.Next:= P^.Next;
P^.Next:= Q;
Q^.info:= P^.Info;
P^.info:= X;
End; End;


Bổ xung 1 nút vào trong danh sách L vào sau một nút đ-ợc trỏ bởi p.
L A

B

Nil

C

X
Prcedure IsertAfter(x:Data;Var L:list; p:pointer)
Var Q: pointer;
Begin
If L= Nil then
Begin
New(L);
L^.info:= x;

Tr n

c Nam

18


L^.Next:= Nil;
End
Else Begin
New(Q);

Q^.Info:= x;
Q^.Next:= p^.Next;
p^.Next:= Q;
End;
End;

Thêm vào giữa hoặc cuối danh sách:Gọi p là địa chỉ của phần tử có
tr-ờng thông tin là x, x đ-ợc chèn vào danh sách. Q là phần tử đứng
ngay tr-ớc P.Ta cần thực hiện b-ớc sau:
+Cho vùng liên kết của P trỏ vào vùng liên kết của Q
+ Cho vùng liên kết của Q trỏ vào P.
First

Nil

X
Fuction InsertItem(P:Pointer; X:Data):Pointer;
Var
P:Pointer;
Begin
New(p);
P^.Info:= X;
P^.Next:=Q^.Next;{Buoc 1}
Q^.Next:=p;
{Buoc 2}
InsertItem:=P;
End;

1.2.3.Loại bỏ một phần tử khỏi danh sách:
Loại bỏ phần tử p ở đầu danh sách: chỉ cần cho con trỏ First vào

vùng liên kết của p.
Procedure DelFirst;
Var
p: pointer ;
Begin
If First < > Nil then
Begin
P:= First;
First:= p^.Next;
Dispose(p);
End;
End;

Tr n

c Nam

19


Loại bỏ phần tử p đứng ngay sau phần tử Q:Cho vùng liên kết của
phần tử Q trỏ đến vùng liên kết của phần tử P.
Procedure DelAfter(Q: pointer);

First

A

Var
P:Pointer;

Begin
P:=Q^.Next;
If p<> Nil then
Begin
Q^.Next:= P^.Next;
Dispose(p);
End;
End;

B
QC
D
E

P

Nil
VD:Lập các giải thuật thực hiện các phép toán đối với danh sách liên kết
đơn nút đầu tiên đ-ợc trỏ bởi L:
a)Nhập liên tục các số khác 0. In danh sách
b)Đếm số l-ợng các nút
c)Bổ xung một nút sau nút thứ k
d)Loại bỏ một nút tr-ớc nút k
e)Chèn 1 danh sách mới sau nút đ-ợc trỏ bởi p
f)Đảo ng-ợc danh sách đã cho.
Giải

Type pt=^node ;
node= record
Info: Integer;

Next: pt;
End;
Var T, L, H: pt; k: integer;
Procedure Nhap;
Var x, k: integer;
Q: pt;
Begin
L:=Nil;
Repeat
Writeln( Nhap vao so nguyen, dung neu nhap 0: );
Write( x= ); readln(x);
If (x<> 0) then
Begin
New(Q);
Q^.info:= x;
Q^.Next:= L;
L:= Q;
End;
Until (x=0);
End;

Tr n

c Nam

20


Procedure InDS(L: pt);
Var P, Q: pt;

Begin
Q:= L;
While(Q<> Nil) do Begin
Write(Q^.info:4);
Q:=Q^Next;
End;
Writeln;
Procedure BoXung;
Var i, k: integer;
Q:pt;
Begin
Write( Vi tri k= ); readln(k);
Write( Nhap gia tri cua nut moi: ); Readln(x);
Q:= L;
L:=0;
While (Q^.Next<> Nil)and(i< k) do
Begin
Q^:= Q^.Next;
i:= i+1;
end;
New(p);
P^.info:= x;
P^.next:= Q^.Next;
Q^.Next:= Q;
End;
Procedure
Loaibo;
Var P, Q: pt;
i: integer;
Begin

P:=L;
For i:=1 to k-2 do
P:= p^.next;
If (P<> L) and(k<>2) then
Begin
Q:= p^.Next;
P^.Next:= Q^.Next;
Dispose(Q);
End
Else
If (k = 2) then
Begin
L:= L^.Next;
Dispose(P);
End;
End;
Procedure ChenDS;
Var P,Q: pt; { Chen H vao sau vi tri k cua DS L}
i: integer;

Begin

P:= L;
For i:=1 to k do
If P^.next<> nil then

Tr n

c Nam


21


P:=P^.Next;
Q:= H;
While Q^.Next<> nil do
Q:= Q^.Next;
Q^.Next:= P^.Next;
P^.Next:= H;

End;
Procedure DaoNguoc;
Var P, Q: pt;
Begin
P:= L; T:= Nil;
While P<> Nil do
Begin
New(Q); Q^.info:= P^.info;
Q^.Next:= T; T:= Q;
P:= P^.Next;
End;
End;
BEGIN {Main}
Writeln( Nhap vao danh sach H: );
Nhap;
Writeln( Nhap vao danh sach L: );
Nhap;
Writeln( Danh sach H la: );
InDs(H);
Writeln( Danh sach L la: );

InDs(L);
Boxung;
Writeln( Danh sach sau khi bo xung: );
InDS(L);
Write( vi tri k= ); readln(k);
Loaibo;
Writeln( Danh sach sau khi loai bo: );
InDs(L);
ChenDS;
Writeln( Sau khi chen H vao L: );
InDs(L);
DaoNguoc;
Writeln( Dao nguoc cua DS L la: );
InDs(T);
Readln;
END.

2.Danh sách liên kết đôi(Doubly Linked List):
2.1.Khái niêm:-Danh sách liên kết đôi là danh sách mà mỗi phần tử của
nó có hai vùng liên kết :
+ Vùng liên kết trỏ đến phần tử đứng ngay tr-ớc nó: liên kết ng-ợc(
Previous)
+ Vùng liên kết trỏ đến phần tử đứng ngay sau nó: liên kết thuận
(Next)

Tr n

c Nam

22



Tổ chức danh sách liên kết đôi nh- sau:
Nil Fist
Prev

Data

Next

Prev

Data

Next

Prev

Data

Next

Prev

Data

Next

Last
-Khai báo dữ liệu:

Type

End;

Nil

Data= integer;
Pt=^Node;
Node= Record;
Info: Data;
Prev, Next: Pt;

-Khởi tạo danh sách liên kết đôi:
Danh sách rỗng First= Nil và Last= Nil
Procedure
Begin
End;

InitList;
First:= Nil;
Last:= Nil;

2.2.Các phép toán xử lý
2.2.1.Thêm một phần tử vào danh sách liên kết đôi:
a) Thêm P vào đầu danh sách:
-Thuật toán:
+B1: Cho liên kết Next của P trỏ tới con trỏ First.
+B2: Cho liên kết Prev của P rỗng
+B3: Nếu danh sách ban đầu khác rỗng thì cho liên kết Prev của First trỏ
đến P

+B4:Cho First trỏ đến P.
+B5: Nếu danh sách ban đầu rỗng thì cho Last trỏ đến P.
Function
Var

Tr n

c Nam

InsertFirst( x: Data): Pt;

23


Begin

P: Pt;

New(P);
P^.info:= x;
P^.Next:= First;
P^.Prev:= Nil;
If First<> Nil then First^.Prev:= P;
First:= P;
If Last= Nil then Last:= P;
InsertFirst:= P;
End;

b)Thêm P vào sau phần tử Q:


Function ChenSau(Q: Pt; x: Data): Pt;
Var
P, R :Pt;
Begin
New(P);
P^.info:= x;
P^.Next:= Q^.Next;
P^.Prev:= Q;
Q^.Next:= P;
R:= P^.Next
If R<> Nil then R^.Prev:= P
Else
Last:= P
ChenSau:= P;
End;

2.2.2.Loại bỏ một phần tử khỏi danh sách liên kết đôi:

Procedure XoaPT(P: Pt);
Var
L, R: Pt; {L: Phan tu dung truoc P;R: Phan tu dung sau P}
Begin
L:= P^.Prev; R:= P^.Next;
If L <> Nil then
L^.Next:= P^.Next;
If R<> Nil then
R^.Prev:= P^.Prev;
If P= First then First:= R;
If P= Last then Last:= L;
Dispose(P);

End;

3.Stack v queue liờn k t :
3.1.Ngăn Xếp(Stack):
3.1.1.Khái niệm: Ngăn xếp( stack) là một kiểu danh sách tuyến tính đặc
biệt mà phép bổ xung và loại bỏ luôn thực hiện ở một đầu đ-ợc gọi là
đỉnh(Top)
- Ngăn xếp hoạt động theo nguyên tắc: Vào sau ra tr-ớc (Last in first
out). Do đó stack còn đ-ợc gọi là danh sách kiểu LIFO.Stack có thể rỗng ,
nghĩa là không có phần tử nào.
3.1.2.Cài đặt:
a)Sử dụng mảng tĩnh:
Tr n

c Nam

24


Const
Type

End;
Var

Max= n;
Data= Integer;
Stack= record
PT: Array[1..Max] of Data;
Top: 0..Max;

S: Stack;

(1).Khởi tạo: S.Top:= 0
Procedure StackInit; {Khoi tao stack rong}
Begin
S.Top:=0;
End;

(2).Kiểm tra rỗng: S.Top= 0?
(3).Kiểm tra đầy: S.Top= Max?
(4).Thêm x vào đỉnh Stack S:

Procedure
Begin

End;

Push(x: Data; var

S : stack);

If S.Top < Max then
Begin
S.Top:= S.Top+1;
S.PT[S.Top]:= x;
End
Else Writeln( Stack da day: );

(5).Loại bỏ một phần tử ở trên đỉnh của ngăn xếp:


Procedure Pop: Data;
Begin
if S.Top= 0 then writeln( Stack rong,ko lay duoc : )
else
Begin
Pop:= S.PT[S.Top];
S.Top:= S.Top
1;
End;
End;

b)Cài đặt bằng danh sách liên kết đơn:
Type

Stack= ^Node;
Node= record
info: Data;
Next: Stack;

End;

Var

S: Stack; {con tro danh sach}

(1).Khởi tạo Stack rỗng:
Procedure StackInit;
Begin
S:= Nil;
End;


(2).Kiểm tra Stack rỗng: S= Nil;
(3).Kiểm tra Stack đầy, không đầy?
Tr n

c Nam

25


×