P. 1
Tai Lieu Quy Hoach Dong

Tai Lieu Quy Hoach Dong

|Views: 362|Likes:
Được xuất bản bởiTuoi Pt

More info:

Published by: Tuoi Pt on Oct 07, 2011
Bản quyền:Attribution Non-commercial

Availability:

Read on Scribd mobile: iPhone, iPad and Android.
download as DOC, PDF, TXT or read online from Scribd
See more
See less

12/08/2014

pdf

text

original

Chương 3 QUY HOẠCH ĐỘNG MỤC TIÊU CỦA CHƯƠNG - Hiểu và nắm vững bản chất của phương

pháp quy hoạch động. - Cung cấp một cách tiếp cận mới trong việc giải quyết các bài toán tối ưu mang bản chất đệ quy. - Sinh viên cần nắm vững phần lý thuyết để có thể hình thành các kỹ năng trong việc tiếp cận và giải các bài toán quy hoạch động. NỘI DUNG BÀI GIẢNG LÝ THUYẾT Quy hoạch động (Dynamic programming) là một kỹ thuật nhằm đơn giản hóa việc tính toán các công thức truy hồi bằng cách lưu trữ toàn bộ hay một phần kết quả tính toán tại mỗi bước với mục đích sử dụng lại. Bản chất của quy hoạch động là nhằm thay thế mô hình tính toán “từ trên xuống” (top-down) bằng mô hình tính toán “từ dưới lên” (bottom-up). Quy hoạch động thường dùng giải các bài toán tối ưu có bản chất đệ qui • Việc tìm nghiệm tối ưu của bài toán đã cho được thực hiện dựa trên việc tìm nghiệm tối ưu của các bài toán con. • Kết quả của các bài toán con được ghi nhận lại để phục vụ cho việc giải các bài toán lớn hơn và giải được bài toán yêu cầu. 3.1. Bài toán quy hoạch Bài toán quy hoạch là bài toán tối ưu: gồm có một hàm f gọi là hàm mục tiêu hay hàm đánh giá, các hàm g1, g2, … gn cho giá trị logic gọi là hàm ràng buộc. Yêu cầu của bài toán là tìm một cấu hình x thỏa mãn tất cả các ràng buộc g1, g2, … gn: gi(x)=TRUE ( ∀ 1 ≤ i i: ≤ n) và x là tốt nhất, theo nghĩa không tồn tại một cấu hình y nào khác thỏa mãn các hàm ràng buộc mà f(y) tốt hơn f(x). Ví dụ: Tìm (x, y) để Hàm mục tiêu : x + y → max Hàm ràng buộc : x2 + y2 ≤ 1 Xét trong mặt phẳng tọa độ, những cặp (x, y) thỏa mãn x2 + y2 ≤ 1 là tọa độ của những điểm nằm trong hình tròn có tâm O là gốc tọa độ, bán kính 1. Vậy nghiệm của bài toán bắt buộc nằm trong hình tròn đó. Những đường thẳng có phương trình x + y = C (C là một hằng số) là đường thẳng vuông góc với đường phân giác góc phần tư thứ nhất. Ta phải tìm số C lớn nhất mà đường thẳng x +

1

y = C vẫn có điểm chung với đường tròn (O, 1). Đường thẳng đó là một tiếp tuyến của đường tròn : x + y = 2 . Tiếp điểm ( 1 2 , 1 2 ) tương ứng với nghiệm tối ưu của bài toán đã cho.

Các dạng bài toán quy hoạch rất phong phú và đa dạng, ứng dụng nhiều trong thực tế, nhưng cũng cần biết rằng đa số các bài toán quy hoạch là không giải được, hoặc chưa giải được. Cho đến nay người ta mới chỉ có thuật toán đơn giải giải bài toán quy hoạch tuyến tính lồi, và một vài thuật toán khác áp dụng cho bài toán cụ thể. 3.2. Phương pháp quy hoạch động Phương pháp quy hoạch động dùng để giải bài toán tối ưu có bản chất đệ quy, tức là việc tìm phương án tối ưu cho bài toán có thể đưa về tìm phương án tối ưu của số hữu hạn các bài toán con. Đối với nhiều thuật toán đệ quy chúng ta đã tìm hiểu, nguyên lý chia để trị thường đóng vai trò chủ đạo trong việc thiết kế thuật toán. Để giải quyết một bài toán lớn, ta chia nó làm nhiều bài toán con cùng dạng với nó để giải quyết độc lập. Trong phương pháp quy hoạch động, nguyên lý này càng được thể hiện rõ : Khi không biết cần phải giải quyết những bài toán con nào, ta sẽ đi giải quyết tất cả các bài toán con và lưu trữ những lời giải hay đáp số của chúng với mục đích sử dụng lại theo một sự phối hợp nào đó để giải quyết những bài toán tổng quát hơn. Đó chính là điểm khác nhau giữa quy hoạch động và phép phân giải đệ quy và cũng là nội dung của phương pháp quy hoạch động :  Phép phân giải đệ quy bắt đầu từ bài toán lớn phân rã thành nhiều bài toán con và đi giải từng bài toán con đó. Việc giải quyết từng bài toán con lại đưa về phép phân rã tiếp thành nhiều bài toán nhỏ hơn và lại đi giải tiếp bài toán nhỏ hơn đó bất kể nó đã được giải hay chưa.  Quy hoạch động bắt đầu từ việc giải tất cả các bài toán nhỏ nhất (bài toán cơ sở) để từ đó từng bước giải quyết những bài toán lớn hơn, cho tới khi giải được bài toán lớn nhất ( bài toán ban đầu). Ta xét một ví dụ đơn giản Dãy Fibonacci là dãy vô hạn các số nguyên dương F[1], F[2],…. được định nghĩa như sau :

2

 1 i ≤ 2 F[1] =   F[i − 2] + F[i − 1] i > 2 
Hãy tính F[6]

Xét hai cách cài đặt chương trình int F(int i) { if(i <=2) return 1 ; return F(i – 2) + F(i – 1) } void main() { cout<<F(6)<< endl; } Cách 1 có hàm đệ quy F(i) để tính số Fibonacci thứ i. Quá trình tính toán có thể vẽ như cây dưới đây. Ta nhận thấy để tính F(6) nó phải tính một lần F(5), hai lần F(4), ba lầm F(3), năm lần F(2), ba lần F(1). } int F(100); // Bang phuong an void main { F[1] = F[2] = 1; for(int i =3; i<=6; i++) F[i] = F[i-2] + F[i -1] cout<<F(6)<< endl;

Hàm đệ quy tính số Fibonacci Cách 2: Trước hết nó tính sẵn F[1] và F[2], từ đó tính tiếp F[3], lại tính tiếp được F[4], F[5], F[6]. Đảm bảo mỗi giá trị Fibonacci chỉ phải tính một lần.
3

nên nếu không đủ không gian vật lý lưu trữ lời giải (bộ nhớ. Các bước cài đặt một chương trình sử dụng quy hoạch động.  Dùng công thức truy hồi phối hợp những lời giải của những bài toán nhỏ đã lưu trong bảng phương án để tìm lời giải của những bài toán lớn hơn và lưu chúng vào bảng phương án. Mỗi gói chỉ chọn 1 hoặc không chọn.  Dựa vào bảng phương án.) để phối hợp chúng thì phương pháp quy hoạch động cũng không thể thực hiện được.  Quá trình từ bài toán cơ sở tìm ra lời giải bài toán ban đầu phải qua hữu hạn bước. M = 13 Tổng giá trị của các gói hàng bỏ vào ba lô: 16 4 . lưu các lời giải vào bảng phương án. Cần chọn những gói hàng nào để bỏ vào một ba lô sao tổng giá trị của các gói hàng đã chọn là lớn nhất nhưng tổng khối lượng của chúng không vượt quá khối lượng M cho trước. Gói hàng thứ i có khối lượng là A[i] và giá trị C[i].1. truy vết tìm ra nghiệm tối ưu 3.  Không gian lưu trữ lời giải các bài toán con để tìm cách phối hợp chúng gọi là bảng phương án của quy hoạch động. Ví dụ: n = 5. Cho tới khi bài toán ban đầu tìm được lời giải. Bài toán ba lô 1 (knapsack) Cho n gói hàng.  Giải tất cả các bài toán cơ sở. Các khái niệm  Bài toán giải theo phương pháp quy hoạch động gọi là bài toán quy hoạch động  Công thức phối hợp nhiều nghiệm của các bài toán con để có nghiệm của bài toán lớn gọi là công thức truy hồi (hay phương trình truy toán) của quy hoạch động  Tập tất cả các bài toán nhỏ nhất có ngay lời giải để từ đó giải quyết các bài toán lớn hơn gọi là cơ sở quy hoạch động. đĩa…. Một số bài toán quy hoạch động 3.Trước khi áp dụng phương pháp quy hoạch động ta phải xem xét phương pháp đó có thỏa mãn những yêu cầu dưới đây hay không:  Bài toán lớn phải phân rã được thành nhiều bài toán con mà có sự phối hợp lời giải của các bài toán con đó cho ta lời giải bài toán lớn.3.  Vì quy hoạch động là đi giải tất cả bài toán con.3.

Các gói được chọn: 1(3. v – A[i]) + C[i] → F(i. 2(4.. 3(5.Điền số 0 cho các ô trên dòng 0 . v) = F(i -1. F(i -1.  Nếu chọn thêm món hàng thứ n thì tổng khối lượng được chọn trong (n-1) món hàng không lớn hơn (M-A[n]) Suy ra bài toán có 2 tham số: số món hàng và khối lượng giới hạn Lập công thức đệ qui Gọi F(i. v) = F(i -1. 5(1.  Trường hợp A[i] > v: F(i. v). F(i -1.Nếu gói hàng thứ i không được chọn thì: F(i.Sử dụng công thức đệ qui và giá trị trên dòng (i -1) để tính dòng i • Trường hợp A[i] > v: F(i.M] chứa giá trị của các F(i. 4). v)  Cách tính giá trị trên bảng phương án: . v – A[i]) + C[i]) } Bài toán nhỏ nhất ứng với i = 0 ta có: F(0. v) = F(i -1.Nếu gói hàng thứ i được chọn thì: F(i. ký hiệu là F(n)  Tham số thể hiện kích thước bài toán là số món hàng n  Giá trị của F(n) có thể được tính từ giá trị của F(n-1) cộng thêm hoặc không cộng thêm giá trị của món hàng thứ n nhưng tổng khối lượng không lớn hơn M.. v) . v) là tổng giá trị lớn nhất của các gói hàng được chọn trong i gói hàng sao cho tổng khối lượng không lớn hơn v. v) = F(i -1.n][0. 6). 1) Tham số thể hiện kích thước bài toán  Kết quả bài toán là tổng giá trị lớn nhất của các món hàng được chọn trong n món sao cho tổng khối lượng không lớn hơn M cho trước. v) • Trường hợp A[i] <= v: F(i. v) = Max{ F(i -1. 5). v – A[i]) + C[i]) } Ví dụ bảng phương án: 5 . v) = Max{ F(i -1. v)  Trường hợp A[i] <= v: . v) = 0 Xây dựng bảng phương án:  Cấu trúc bảng phương án: Dùng mảng F[0. v).

v] = F[i-1.n][0.  Nếu F[ i. v] = F[ i-1. v-A[i]]. 6 . v) = F(i -1. v] <> F[i–1. v) = Max{ F(i -1.A[i] ] + C[i]..• Trường hợp A[i] > v: F(i. v]. F(i -1.. v) • Trường hợp A[i] <= v: F(i. v] < F[i-1. i <= n. } } Truy vết tìm lại các gói hàng đã chọn Bắt đầu từ ô F[n. v++) F[0. v] thì gói thứ i được chọn. v). i++) for (v=0. M] trên dòng n ta dò ngược về dòng 0 theo nguyên tắc:  Nếu F[ i. v]. ta truy tiếp ô F[i-1. v] = 0. v] = F[i–1. v – A[i]) + C[i]) } Thuật toán tạo bảng phương án void TaoBangPhuongAn(F[0.M]) { for (v=0. v . // Điền số 0 cho dòng 0 của bảng for (i = 1. v] thì gói thứ i không được chọn. if (A[i] <= v && F[i. v <= M. v <= M. ta truy tiếp ô F[i-1. v . v++) { F[i.A[i] ] + C[i]) F[i.

v]) { <Món hàng thứ i được chọn >. for (. v = v – A[i].Bài toán ba lô 2 Cho n loại hàng.3.n][0.. v = M. } } 3. Cần chọn các món hàng trong từng loại để bỏ vào một ba lô sao cho tổng giá trị của các món hàng đã chọn là lớn nhất nhưng tổng khối lượng của chúng không vượt quá khối lượng M cho trước.2. i --) if (F[i. Số lượng các món hàng của mỗi loại không hạn chế. v] != F[i-1.M]) { Bắt đầu từ ô F[n. i > 0.. Cho biết số lượng món hàng từng loại hàng được chọn Ví dụ: n = 5.Thuật toán truy vết tìm lại các gói hàng đã chọn void TruyVet(F[0. Món hàng thuộc loại hàng i có khối lượng A[i] và giá trị C[i]. M] trên dòng n: i = n. M = 13 Tổng giá trị của các món hàng bỏ vào ba lô: 19 Các món được chọn: 1 gói hàng loại 1 có khối lượng 3 và giá trị 4 5 gói hàng loại 4 có khối lượng 2 và giá trị 3 Xác định công thức đệ quy 7 .

v) = F(i-1.Điền số 0 cho các ô trên dòng 0 và cột 0 của bảng F . v) = F(i-1.Nếu loại hàng i không được chọn thì: F(i. v) .A[i] > v : F(i. v/A[i]] Xây dựng bảng phương án:  Cấu trúc bảng phương án: dùng 2 mảng . v] = k  Cách tính giá trị trên bảng phương án: .M]: F[i. v) 8 . v – A[i]*k) + C[i]*k } k ∈ [0.Gọi F(i.M]: S[i..1.Mảng F[0.v] chứa số món hàng loại i được chọn Nếu F(i. v) . v] = 0 Ngược lại S[i. v): S[i. v) = F(i . v) = F(i-1. v – A[i]*k) + C[i]*k Do đó: F(i.n][1.1.A[i] <= v : F(i. v) . v – A[i]*k) + C[i]*k } với k ∈ [0.A[i] > v : F(i. v/A[i]] Bài toán nhỏ nhất ứng với i = 0 hay v=0 ta có: F(0.Mảng S[1.Nếu có k món hàng loại i được chọn: (1 <= k <= v/A[i] ) F(i. v) = 0  Với i > 0 : . v) = Max{F(i-1. v) = F(i .1. v) là tổng giá trị lớn nhất của các món hàng được chọn có tổng khối lượng <= v trong i loại hàng đầu tiên  Với i = 0 : F(i.. v)  Trường hợp A[i] <= v: .. v) = F(i .Sử dụng công thức đệ quy và giá trị trên dòng i -1 để tính dòng i của bảng F và bảng S Ví dụ: Lập bảng phương án F  Với i > 0 : . v) là tổng giá trị lớn nhất của các món hàng được chọn sao cho tổng khối lượng <= v trong i loại hàng. v) = Max{ F(i-1. v) = 0 Công thức đệ quy Gọi F(i.n][0..  Trường hợp A[i] > v: F(i. v] chứa giá trị của các F(i.

.A[i] <= v : F(i. v] = 0. v] Thuật toán tạo bảng phương án void TaoBangPhuongAn(F[0. v] < F[i-1. v] = F[i-1.n][0.. S[i. S[1. v . v . k++) if (F[i.A[i]*k ] + C[i]*k) { F[i.n][0. i <= n. k <= v/A[i]..M].v) Bảng S[i. 9 .. v] = k. v] = F[i-1. S[i.M]) { <Điền số 0 cho dòng 0 và cột 0 của bảng F[0. v) = Max{ F(i-1. v++) { F[i. for (i = 1.. v <= M.. if (v >= A[i]) for(k = 1. i++) for (v=1.n][1.M]>..A[i]*k ] + C[i]*k. v]. v – A[i]*k) + C[i]*k } với k ∈ [0. v/A[i] ] Bảng F(i.

Truy tiếp ô S[i-1. v]. v] <> 0 thì : . Bài toán dãy con có tổng chia hết cho k 10 .  Nếu S[i. . v = M while (i > 0) { if (S[i. v] .Loại hàng i không được chọn. v . Thuật toán truy vết tìm lại các gói hàng đã chọn void TruyVet(S[1.S[i. } i = i – 1.n][1. v] != 0) { <in số lượng gói hàng i trong S[i. } } 3.3... M] trên dòng n ta dò ngược về dòng 1 theo nguyên tắc:  Nếu S[i.Truy tiếp ô S[i-1. v] >.3. v]*A[i].Loại hàng i được chọn với số lượng là S[i. v] = 0 thì : .M]) { i = n. v]*A[i] ]. v = v – S[i.} } } Truy vết tìm lại các gói hàng đã chọn Bắt đầu từ ô S[n.

(-r) mod k = (.Nếu r > 0 : do (r + k .(i-1)] có tổng chia với k dư (k-r) Tham số thể hiện kích thước của bài toán: kích thước miền và số dư của tổng chia với k Lập công thức đệ qui Gọi F(i.. Nếu dãy con dài nhất không có A[i] thì F(i) = F(i-1) Với F(i-1) = chiều dài dãy con dài nhất trong miền [1.r) mod k = 0 nên F(i-1) bằng chiều dài dãy con dài nhất trong miền [1.r + k) mod k 3.... v) = chiều dài dãy con dài nhất trong miền [1.i] có tổng chia hết cho k.i-1] có tổng chia hết cho k 2.Nếu r = 0: thì F(i-1) = chiều dài dãy con dài nhất trong miền [1. (r + z) mod k = v → z = (v – r) mod k = (v – r + k) mod k 2 6 5 20 6 8 Xác định tham số Gọi F(i) = chiều dài dãy con dài nhất trong miền [1.i] có tổng chia với k dư là v. 1.Cho một dãy A gồm n số nguyên và một số nguyên dương k.1] có tổng chia hết cho k . 11 .i. Ví dụ: n = 6 và k = 5 Chiều dài dãy con: 4 Các phần tử được chọn là : 1 Có giá trị tương ứng là : : 11 Nhắc lại phép toán mod Giả sử r = a mod k và z = b mod k Ta có: 1. Hãy tìm một dãy con (không nhất thiết phải liên tiếp nhau) dài nhất có tổng các số chia hết cho số k.. (a + b) mod k = (r + z) mod k 2. Nếu dãy con dài nhất có chứa A[i]: thì F(i) = F( i-1) + 1 Gọi r = A[i] mod k .

v) 2. v-r+k) + 1 thay (v . v . v).v)= 1 nếu r = v Công thức đệ quy Gọi r = A[i] mod k  Với i = 1: .Nếu v – r > 0 và F(i-1. v).Nếu v<>r và F(i-1. v – r + k) + 1} Tinh chế công thức đệ quy Gọi r = A[i] mod k • Với i = 1: .r) >0 thì F(i. 0) +1 } . v). v) = F(i-1. v) = F( i-1.1. v) = 1 nếu r = v • Với i > 1 : . v. v – r) +1 } .Nếu v < r và F(i-1. v) = F( i-1. v). v) = F(i-1. (v. 0) +1 } . v) = 0 nếu r <> v .Nếu v > r và F(i-1.F(1. F(i-1. v-r+k)>0: F(i.F(1. Nếu dãy con dài nhất có chứa A[i]: Gọi r = A[i] mod k ta có F(i.r +k) mod k) > 0 thì F(i. v) = Max {F(i-1.r) + 1 . v) = F(i-1.v)= 0 nếu r <> v • F(1. v – r + k)>0 thì F(i.F(1. v) = Max{F(i-1. (v – r + k) mod k) +1 } Xây dựng bảng phương án:  Cấu trúc bảng phương án: 12 . v). v) = 1 nếu r = v  Với i > 1 : .Nếu v – r = 0 : F(i.r)>0: F(i. Nếu dãy con dài nhất không có A[i] thì F(i. F(i-1. F(i-1. F(i-1.Nếu v = r thì : F(i.Nếu v – r < 0 và F(i-1. v) = Max {F(i-1. v) = 0 nếu r <> v . v) = Max {F(i-1. v) = Max {F(i-1. F(i-1. v .Nếu v = r thì : F(i.F(1.r) mod k = (v – r + k) mod k Bài toán nhỏ nhất ứng với i = 1: • F(1. v . 0) + 1 .r) + 1 .

v] = F[i-1.. if (v == r && F[i. i++) for (v=0. v) = Max {F(i-1.K-1] chứa giá trị của các F(i.Dùng mảng F[1. (v-r+k) mod k) > 0 thì F(i. 0] + 1.k-1]) { for (v=0. v <= k-1. v++) { r = A[i] % k... (v . v] = F[ i -1. F(i-1. v) = Max {F(i-1.Điền giá trị dòng 1: Nếu A[1] mod k = v thì F[1. v] = 1 ngược lại F[1. } } 13 . v] <= F[i-1.Nếu v = r thì : F(i. v] = F[i-1.. v] <= F[i-1. (v . v++) F[1. (v – r + k) mod k) +1 } i 1 2 3 4 5 6 r = A[i] | v 1 1 2 2 0 3 0 0 4 | 0 3 | 0 3 | 3 0 | 4 2 | 4 1 1 0 | 1 4 | 1 4 | 3 1 | 4 3 | 4 2 0 1 | 2 0 | 2 0 | 2 2 | 3 4 | 5 3 0 0 | 2 1 | 2 1 | 2 3 | 3 1 | 5 4 0 3 | 0 2 | 3 2 | 3 4 | 4 2 | 6 Thuật toán tạo bảng phương án void TaoBangPhuongAn(F[1. v <= k-1. (v .n][0. else if (F[i-1. F[i. for (i = 2.r + k)%k]) F[i. 0) +1 } .Nếu v<>r và F(i-1. v)  Cách tính giá trị trên bảng phương án: . F(i-1. v] = 0 . v] = (A[i]%k == v) ? 1 : 0. v).r + k)%k] >0 && F[i.r + k)%k] + 1.Sử dụng công thức đệ quy và giá trị trên dòng i -1 để tính dòng i Ví dụ bảng phương án: • Với i > 1 : . 0 ]) F[i. v]. v).n][0. i <= n.

v]. (v-r+k)%k]. Ví dụ: với n = 10 và dãy A được cho trong bảng.. ta truy tiếp ô F[i -1. (v-r+k)%k]: . Hãy chỉ ra dãy con không giảm dài nhất ? Xác định tham số thể hiện kích thước bài toán  Gọi L(n) là độ dài dãy con không giảm dài nhất trong miền [1.  Xét 2 cách ghi nhận kết quả các bài toán con: 14 .n-1] có A[n]  Do đó tham số thể hiện kích thước bài toán là số phần tử n. (v-r+k)%k] > 0 và F[i.A[i] được chọn .4.. v] > F[i–1.Truy tiếp ô F[i -1. 0] trên dòng n ta dò ngược về dòng 0 theo nguyên tắc: • Nếu F[i–1. In ra dãy con đó..n-1] không có A[n] .L(n) = L(n-1) +1 nếu dãy con dài nhất trong miền [1.3. • Ngược lại thì A[i] không được chọn.Tìm dãy con không giảm dài nhất Cho một dãy gồm n số nguyên. i 1 2 3 4 5 6 r = A[i] | v 1 1 2 2 0 3 0 0 4 | 0 3 | 0 3 | 3 0 | 4 2 | 4 1 1 0 | 1 4 | 1 4 | 3 1 | 4 3 | 4 2 0 1 | 2 0 | 2 0 | 2 2 | 3 4 | 5 3 0 0 | 2 1 | 2 1 | 2 3 | 3 1 | 5 4 0 3 | 0 2 | 3 2 | 3 4 | 4 2 | 6 3.n] . Hãy loại bỏ khỏi dãy một số phần tử để được một dãy con không giảm dài nhất.L(n) = L(n-1) nếu dãy con dài nhất trong miền [1.Truy vết Bắt đầu từ ô F[n.

Mảng Truoc[1. i++) 15 ..n]: L[i] chứa giá trị của L(i) .n]: Truoc[i] ghi chỉ số phần tử kề trước i trong dãy con dài nhất mà i là phần tử cuối dãy. Cách tính giá trị trên bảng phương án: .Với các phần tử i từ 2 đến n: • Nếu A[i] < A[j] với mọi j < i thì: L(i) = 1 và Truoc(i) = 0 • Ngược lại thì .Lập công thức đệ qui Gọi L(i) là độ dài dãy con dài nhất trong dãy A[1.1] thì L(1) = 1 Xây dựng bảng phương án: ..L(i) = Max{ L(j) : j < i và A[j] <= A[i] } + 1 . Nếu A[i] < A[j] với mọi j < i thì: L(i) = 1 Ngược lại thì : L(i) = Max{ L(j) : j < i và A[j] <= A[i] } + 1 Bài toán nhỏ nhất với đoạn A[1. for (i = 2. Truoc[1] = 0.Mảng L[1.i] và có A[i] là phần tử cuối dãy con dài nhất đó...Gán L[1] = 1 và Truoc[1] = 0 .Truoc[i] = k sao cho L(k)= Max{ L(j) : j < i và A[j] <= A[i] } Thuật toán tạo bảng phương án void TaoBangPhuongAn() { L[1] = 1. i <= n.

{ L[i] = 1. j--) if (B[j] > B[i]) i = j. Truoc[i] = j. while ( i > 0) { <in thông tin A[i] thuộc dãy con tối ưu>. j--) if (A[j] <= A[i] && L[j] >= L[i]) { } L[i] = L[j] + 1. for (j = i-1. j >=1. i = Truoc[i]. Thuật toán tìm lại các phần tử trên dãy con tối ưu void TruyVet() { i = n. Truoc[i] = 0. for ( j = n-1. j >= 1. 16 . Truy tiếp sang phần tử có chỉ số Trươc[i] cho đến khi phần tử Truoc[i] = 0. } } Truy vết tìm lại các phần tử trên dãy con Bắt đầu từ phần tử i có giá trị L[i] có lớn nhất là phần tử cuối cùng trong dãy con dài nhất.

3.Tiền dịch vụ nếu số nhân công của tháng T lớn hơn số nhân công tháng T-1 hay tiền sa thải nếu số nhân công trong tháng T nhỏ hơn số nhân công của tháng T-1. j) = j * (DV + LT) với j = Scn[1]. Cần phải thuê hay sa thải bao nhiêu công nhân mỗi tháng để tổng chi phí nhân công của dự án là nhỏ nhất. 17 . tiền đền bù khi sa thải một công nhân là ST.5. người quản lý cần phải lập lịch sử dụng công nhân mỗi tháng cho dự án. Biết rằng.Smax  C(i. Lập lịch thuê nhân công Có một dự án kéo dài trong T tháng.  Kích thước bài toán phụ thuộc vào 2 tham số: số tháng và số nhân công của tháng Lập công thức đệ qui  Scn[i] lưu số công nhân cần thuê cho tháng thứ i  Smax là số công nhân của tháng cần nhiều người nhất  Bài toán con nhỏ nhất ứng với i = 1 (tháng đầu tiên): C(1. j) là chi phí tối thiểu của i tháng đầu tiên nếu tại tháng thứ i có j công nhân được thuê. } 3. Xác định tham số thể hiện kích thước bài toán  Tham số thể hiện kích thước bài toán là số tháng T  Tổng chi phí nhân công trong T tháng được tính từ tổng chi phí nhân công của T-1 tháng cộng thêm chi phí trả nhân công của tháng thứ T. tiền dịch vụ khi thuê một công nhân mới là DV.. lương tháng mỗi công nhân phải trả là LT.Tiền lương trả cho số nhân công của tháng T và . số công nhân tối thiểu cần trong tháng thứ i là Scn[i].  Chi phí trả nhân công của tháng thứ T bao gồm : .} <in thông tin A[i] thuộc dãy con tối ưu>.

j <= Smax. j =Scn[i].. for (i = 2. j)  Mảng C[1....T+1. j] Thuật toán tạo bảng phương án C và Truoc { for (j=Scn[1]..Smax Xây dựng bảng truy vết số công nhân Mảng Truoc[1. k) + chi phí để từ k người thành j người } ( i=1.T.Smax) C(T+1.Smax]: Truoc[i.. j) C(1.Smax]: C[i. j) = Min{ C(i-1.. j++) C[1. j++) 18 . i <= T.C(i.T. j) = C(T. k) + chi phí để từ k người thành j người } ( i=2.. j) + (j * ST) j=Scn[T]..Smax...Smax)  Kết quả bài toán là: Kq = Min{C(T.Smax C(i. j] := k là số người thuê ở tháng thứ i-1 để có C[i.. j =Scn[i].. k = Scn[i-1]. j) = Min{ C(i-1. j] ghi nhận giá trị C(i. k = Scn[i-1]. 1. 1. j] = j * (DV + LT).Smax.T. j <= Smax. j) + chi phí sa thải j người} j=Scn[T].Smax Xây dựng bảng chứa C(i. j) = j * (DV + LT) với j = Scn[1]. i++) for (j=Scn[i].

k]. k <= Smax. j++) C[T+1. Cho n loại tờ giấy bạc. k] . thì thông báo “KHONG DOI DUOC”. gói thứ i có Ai cái kẹo. Có N gói kẹo. k = Scn[T]. j <= Smax. Nếu không đổi được. S =C[T+1. Nếu không đổi được.{ C[i. 4. Cần chi trả cho khách hàng số tiền M đồng. Hãy cho biết mỗi loại tiền cần bao nhiêu tờ sao cho tổng số tờ là ít nhất. j ]. i--) { } } Bài tập 1. Tờ giấy bạc thứ i có mệnh giá A[i]. Giả thiết loại tiền mệnh giá A[i] có B[i] tờ (i := 1. 2. } } } for (j=Scn[T]. j] = X. i > 1. } <Tháng T cần k công nhân> for (i=T. j] = C(T. for (j=Scn[T]+1. 3. k++) { X = C[i-1. j ]) { k = j. } Thuật toán truy vết số công nhân mỗi tháng { //Tìm số nhân công của tháng thứ T S = C[T+1. j++) if (S > C[T+1. Với mỗi loại hoa i ta biết giá trị thẩm mỹ khi cắm hoa đó k = Truoc[i. Cần chi trả cho khách hàng số tiền M đồng. n). j] = MAXINT. j <= Smax. thì thông báo “KHONG DOI DUOC”. for (k=Scn[i-1]. if (k > j) X = X + (k – j)*DV. Số tờ mỗi loại không giới hạn. j] = k. Tờ giấy bạc thứ i có mệnh giá A[i]. Hãy cho biết mỗi loại tiền cần bao nhiêu tờ sao cho tổng số tờ là ít nhất. Cho n loại tờ giấy bạc. Cần cắm k loại hoa khác nhau vào n lọ xếp thẳng hàng sao cho loại hoa có số hiệu nhỏ được đặt trước hoa có số hiệu lớn. Truoc[i. Scn[T] ]. Không được bóc bất kỳ một gói kẹo nào. j) + (j * ST) . cần chia N gói kẹo thành hai phần sao cho độ chênh lệch số kẹo giữa hai gói là ít nhất. else X = X + (j – k)*ST if (X< C[i. j]) { C[i. <Tháng i-1 cần k công nhân> 19 .

a. Do số lượng nhân sự của công ty có hạn. b. Hợp đồng thứ i có giá trị là Ci (số nguyên) và cần Ai nhân sự để thực hiện. cho biết tổng giá trị của các hợp đồng đã chọn. Để thuận lợi cho việc dẫn nước. theo nguyên tắc ngọn đồi sau phải cao hơn ngọn đồi trước. nên Công ty muốn ưu tiên chọn một số hợp đồng để thực hiện trước sao cho tổng giá trị của các hợp đồng đã chọn là lớn nhất nhưng tổng số nhân sự thực hiện các hợp đồng đó không vượt quá số lượng M nhân sự (M ≤ 100) hiện có của công ty. 6. mỗi ngọn đồi được gán một số thứ tự tăng theo hướng từ thung lũng lên vùng cao. liệt kê kích thước các file đã chọn. hai trạm bơm kề nhau không nhất thiết đặt trên hai ngọn đồi kề nhau. M ≤ 100. Hãy trình bày thuật toán để chọn trong N file dữ liệu các file đính kèm vào một thư điện tử theo yêu cầu trên. Hãy trình bày thuật giải để chọn lựa các hợp đồng theo yêu cầu trên. Giả sử. 5. 7. người ta cần chọn trong N file dữ liệu các file để đính kèm vào một email sao cho tổng dung lượng của các file đính kèm là lớn nhất nhưng không vượt quá kích thước M. phải xây dựng kéo hệ thống dẫn nước từ dưới thung lũng lên bản băng qua các ngọn đồi. người ta đặt các trạm bơm nối tiếp trên từng ngọn đồi dẫn từ thung lũng lên bản vùng cao.vào lọ j là v[i. Một hộp thư điện tử cho phép gửi đính kèm một hoặc nhiều file vào một thư điện tử sao cho tổng dung lượng các file đính kèm trên thư điện tử không vượt quá kích thước M KByte cho trước. Để có số thư điện tử gửi đi là ít nhất. nên Công ty muốn ưu tiên chọn một số hợp đồng để thực hiện trước sao cho tổng giá trị của các hợp đồng đã chọn là lớn nhất nhưng tổng số nhân sự thực hiện các hợp đồng đó không vượt quá số lượng M nhân sự (M ≤ 100) hiện có của công ty. ngọn đồi thứ i có độ cao Ai (là một số nguyên dương). Giả sử có N ngọn đồi (N ≤ 100).j]. Một công ty máy tính nhận được N hợp đồng (N ≤ 50) lắp đặt hệ thống máy tính tại N công ty. N ≤ 50 và file thứ i trong N file dữ liệu có kích thước là Ai KByte (là số nguyên dương). cho biết tổng giá trị của các hợp đồng đã chọn. giá trị hợp 20 . Hợp đồng thứ i có giá trị là Ci (số nguyên) và cần Ai nhân sự để thực hiện. Sử dụng ngôn ngữ C++ cài đặt giải thuật trên. Việc xây dựng công trình cấp nước sạch ở các bản vùng cao rất khó khăn. giá trị hợp đồng và số lượng nhân sự của các hợp đồng đã chọn. 8. Hãy trình bày giải thuật chọn lựa ra các ngọn đồi đặt các trạm bơm sao cho số ngọn đồi được chọn là nhiều nhất. Hãy trình bày thuật giải để chọn lựa các hợp đồng theo yêu cầu trên. Do số lượng nhân sự của công ty có hạn. Một công ty máy tính nhận được N hợp đồng (N ≤ 50) lắp đặt hệ thống máy tính tại N công ty. Hãy tìm phương án cấm các loại hoa trên vào n lọ sao cho tổng giá trị thẩm mỹ là lớn nhất.

21 .

Biểu diễn hình học một cây 22 . Một ví dụ điển hình về cây là tập hợp các thành viên trong một dòng họ với quan hệ cha con. và C là con của P • Có đường đi duy nhất từ gốc tới mỗi đỉnh của cây.Chương 4 CÂY MỤC TIÊU CỦA CHƯƠNG . NỘI DUNG BÀI GIẢNG LÝ THUYẾT 4. Đỉnh P được gọi là cha của đỉnh C.1. các khái niệm cơ bản về cây và các CTDL biểu diễn cây .Sinh viên cần nắm vững phần lý thuyết để có thể hình thành các kỹ năng trong việc tiếp cận và giải các bài toán cụ thể. thì trong đồ thị có cung đi từ đỉnh A tới đỉnh B.Các khái niệm cơ bản Chúng ta có thể xác định khái niệm cây bằng hai cách: đệ quy và không đệ quy.1. hàng dưới là các đỉnh con của gốc. có đoạn nối từ đỉnh cha tới đỉnh con (cần lưu ý cung luôn luôn đi từ trên xuống dưới) Hình 4. tồn tại duy nhất một đỉnh P có cung đi từ P đến C. Biểu diễn dòng họ dưới dạng đồ thị hướng: quan hệ cha con được biểu diễn bởi các cung của đồ thị. . Xem xét các đặc điểm của đồ thị định hướng này. chúng ta đưa ra định nghĩa cây như sau: Cây là một đồ thị định hướng thỏa mãn các tính chất sau: • Có một đỉnh đặc biệt được gọi là gốc cây • Mỗi đỉnh C bất kỳ không phải là gốc. mỗi một người trong dòng họ là con của một người cha nào đó trong dòng họ.Nghiên cứu một lớp cây đặc biệt: cây nhị phân. Trước hết chúng ta đưa ra định nghĩa cây thông qua các khái niệm trong đồ thị định hướng. Trừ ông tổ của dòng họ này. Người ta quy ước biểu diễn cây như trong hình 4. dưới một hàng là các đỉnh con của các đỉnh trong hàng đó. nếu A là cha của B.1: gốc ở trên cùng.Hiểu và nắm vững bản chất.

Trong biểu diễn hình học. D là anh em. thì cây con gốc A được gọi là cây con của gốc. Độ sâu của một đỉnh là độ dài đường đi từ gốc tới đỉnh đó. Ví dụ. trong cây ở hình 4. Cây là một tập hợp không rỗng T các phần tử (được gọi là các đỉnh) được xác định đệ quy như sau: • gốc là a. khi đó đỉnh b1 được gọi là con cả của a. Độ cao của cây là số đỉnh nằm trên đường đi dài nhất từ gốc tới một lá. đỉnh b k là đỉnh ngoài cùng bên phải. Mở rộng của quan hệ cha con. Sau này chúng ta chỉ quan tâm đến các cây được sắp. Một đỉnh bất kỳ A cùng với tất cả các con cháu của nó lập thành một cây gốc là A. cây này có 23 . G. C. G. Chẳng hạn. còn đỉnh bi+1 (i=1.. các đỉnh trong cùng một mức là đỉnh con của một đỉnh nào đó ở mức trên. là quan hệ tổ tiên con cháu.1.. đỉnh G có độ sâu là 2. Nếu đỉnh A là con của gốc.Sau đây chúng ta sẽ đưa ra một số thuật ngữ hay được dùng đến sau này. Chẳng hạn. b2. mức 2 gồm các đỉnh A.1 các đỉnh B. D. . mức 3 gồm các đỉnh E. Các đỉnh cùng cha được xem là anh em.. C. hay B là con cháu của A. Chẳng hạn.1 có độ cao là 3.. C. Dễ dàng thấy rằng. B. Tập chỉ có một đỉnh a là cây. F. Giả sử a là một đỉnh và các con của nó được sắp xếp theo thứ tự b1.1. trong hình 4. 2. Cây là một cấu trúc dữ liệu phân cấp: Các đỉnh của cây được phân thành các mức. gốc cây là tổ tiên của các đỉnh còn lại trong cây.k-1) được gọi là em liền kề của đỉnh bi. Các đỉnh không có con được gọi là lá.1 được phân thành 3 mức: mức 1 chỉ gồm có gốc. Độ cao của cây chính là mức lớn nhất của cây. Trong hình 4. Định nghĩa đệ quy. bk (k ≥1). cây trong hình 4. Mức của mỗi đỉnh được xác định đệ quy như sau: Gốc ở mức 1 Mức của một đỉnh = mức của đỉnh cha + 1 Như vậy. Chẳng hạn. Khái niệm cây còn có thể định nghĩa một cách khác: định nghĩa đệ quy. . độ cao của cây là độ cao lớn nhất của cây con của gốc cộng thêm 1. Cây được sắp là cây mà các đỉnh con của mối đỉnh được sắp sếp theo một thứ thứ tự xác định. Trên đây chúng ta đã định nghĩa cây như một đồ thị định hướng có một số tính chất đặc biệt. Trong cây nếu có đường đi từ đỉnh A tới đỉnh B thì A được gọi là tổ tiên của B. cây trong hình 4. F. các đỉnh lá là E. Cây này được gọi là cây con của cây đã cho.. Một đỉnh không phải là lá được gọi là đỉnh trong. đỉnh con cả là đỉnh ngoài cùng bên trái.

. Và như vậy. Sau đây. Node* child [K]. chúng ta trình bày hai phương pháp cài đặt cây thông dụng nhất. . k).. r2. trong đó hai cây bất kỳ không có đỉnh chung... con trỏ root: root Node <Item>* root. k) lập thành một cây có gốc là đỉnh r.2. k) được gọi là các cây con của gốc r.. Chúng ta có thể sử dụng mảng để cài đặt cây. Giả sử. Cây T được biểu diễn hình học như sau: • Sử dụng định nghĩa cây đệ quy.. cây trong hình 4.. mỗi đỉnh chỉ có nhiều nhất K đỉnh con. }. Các cây Ti (i=1.. Phương pháp 1 (chỉ ra danh sách các đỉnh con của mỗi đỉnh)..Giả sử T1. ít được sử dụng. Chúng ta có thể truy cập tới một đỉnh bất kỳ trong cây bằng cách đi theo các con trỏ bắt đầu từ gốc cây. . khi đó ta có thể mô tả mỗi đỉnh bởi cấu trúc sau: const int K = 10. ta sử dụng một con trỏ trỏ tới một đỉnh con của nó. ... Khi đó tập T gồm đỉnh r và tất cả các đỉnh trong các cây Ti (i=1. mỗi đỉnh của cây được biểu diễn bởi một cấu trúc gồm hai thành phần: một biến data lưu dữ liệu chứa trong đỉnh đó và một mảng child các con trỏ trỏ tới các đỉnh con. và r là đỉnh cha của đỉnh ri hay ri là đỉnh con của r (i=1. Vì vậy.....1 được cài đặt bởi CTDT được biểu diễn hình học trong hình 4. Song cách này không thuận tiện. Cài đặt cây Cây có thể cài đặt bởi các CTDL khác nhau. Với mỗi đỉnh của cây..... Giả sử r là một đỉnh mới không có trong các cây đó. .. Tk (k ≥ 1) là các cây có gốc tương ứng là r1. T2. rk . template <class Item> { Item data. ta cần có một con trỏ ngoài trỏ tới gốc cây. chúng ta có thể dễ dàng đưa ra các thuật toán đệ quy cho các nhiệm vụ xử lý trên cây. A với cách cài đặt này. B C D 24 E F G .

Trong trường hợp đó. B C D E F G 25 . nextSibling. ta chỉ sử dụng hai con trỏ: con trỏ firstChild trỏ tới đỉnh con cả và con trỏ nextSibling trỏ tới em liền kề. Dễ dàng thấy rằng.Hình 4. Chúng ta cũng cần có một con trỏ ngoài root trỏ tới gốc cây như trong phương pháp 1. các con trỏ nextSibling liên kết các đỉnh tạo thành một danh sách liên kết biểu diễn danh sách các đỉnh con của mỗi đỉnh. Cài đặt cây bởi mảng con trỏ. Thay vì sử dụng mảng con trỏ. firstChild. sẽ lãng phí bộ nhớ. số đỉnh con của các đỉnh có thể rất khác nhau.1 được cài đặt bởi CTDL như trong hình 4. Node*. Mỗi đỉnh của cây được biểu diễn bởi cấu trúc sau: template <class Item> struct { Item Node* }. Trong một cây. Với cách này. nếu sử dụng mảng con trỏ. ta có thể truy cập tới đỉnh bất kỳ trong cây. xuất phát từ gốc đi theo con trỏ firstChild hoặc con trỏ nextSibling. Phương pháp 2 (chỉ ra con cả và em liền kề của mỗi đỉnh).3. cây trong hình 4.2. root A Node data. Ta có nhận xét rằng.

2. chỉ trừ khi nào không xuống dưới được nữa mới quay lên đỉnh cha để rồi lại tiếp tục đi xuống. G. Giả sử T là cây có gốc r và các cây con của gốc là T1. 26 . D. Khi không đi sâu xuống được.. Duyệt cây có nghĩa là lần lượt thăm các đỉnh của cây theo một trật tự nào đó và tiến hành các xử lý cần thiết với các dữ liệu trong mỗi đỉnh của cây. T2. Chẳng hạn. Chúng ta xác định các phương pháp duyệt cây này.4..1. rồi lại tiếp tục đi xuống.3. Thứ tự các đỉnh được thăm theo phương pháp này là A. E. Cài đặt cây sử dụng hai con trỏ... rồi lại tiếp tục đi xuống thăm con cả của r 1. luôn luôn đi sâu xuống thăm các đỉnh con.. Duyệt cây T theo thứ tự trước có nghĩa là: • Thăm gốc r. ta có thể đưa thêm vào cấu trúc Node một con trỏ parent trỏ tới đỉnh cha.Hình 4. ta quay lên cha của nó và đi xuống thăm một đỉnh con tiếp theo (nếu có) của đỉnh cha đó.. theo thứ tự trong (inorder) và theo thứ tự sau (postorder). Các phương pháp duyệt cây được mô tả rất đơn giản bằng đệ quy. Khi dữ liệu được tổ chức dưới dạng cây. Cần chú ý rằng. Tk (k>=0). 4. Có ba phương pháp duyệt cây hay được sử dụng nhất trong các ứng dụng là: duyệt cây theo thứ tự trước (preorder). tức là đạt tới một đỉnh không có con (lá). ... Quá trình đi thăm các đỉnh của cây trong hình 4. Như vậy. • Duyệt lần lượt các cây con T1. C.1 được biểu diễn bởi hình 4.. F. chẳng hạn như in ra các dữ liệu đó. ta rút ra quy luật đi thăm các đỉnh của cây như sau: đầu tiên thăm gốc r . duyệt cây theo thứ tự trước có nghĩa là xuất phát thăm từ gốc. Phân tích kỹ thuật duyệt cây theo thứ tự trước. B. trong một số trường hợp. để thuận tiện cho các xử lý. xét cây trong hình 4. Do đó.. Duyệt cây Người ta thường sử dụng cây để tổ chức dữ liệu. kỹ thuật duyệt cây theo thứ tự trước còn được gọi là kỹ thuật tìm kiếm theo độ sâu. sau đó đi xuống thăm con cả r 1 của gốc (r1 là gốc của cây con T1).. Tk theo thứ tự trước. thì hành động hay được sử dụng là duyệt cây.

C.1 được thăm theo thứ tự là E. while (P ! = NULL) . node <Item>* { Preorder (P. F. Bây giờ chúng ta cài đặt các hàm duyệt cây. Lưu ý rằng. void f(Item&)) P = root  firstChild... Duyệt cây T theo thứ tự sau được tiến hành như sau: • Duyệt lần lượt các cây con T1. A.4. Chúng ta đưa vào hàm Preorder một tham biến khác. . A.Tk theo thứ tự sau • Thăm gốc r Chẳng hạn.. G. cũng với cây trong hình 4. đó là hàm với khai báo sau: void f(Item&). Khi đó hàm đệ quy Preorder được cài đặt như sau: template <class Item> void { if (root ! = NULL) { f (root  data). P = P  nextSibling. Thăm các đỉnh của cây theo thứ tự trước Duyệt cây T theo thứ tự trong được quy định như sau: • Duyệt cây con T1 theo thứ tự trong • Thăm gốc r • Duyệt lần lượt các cây con T2. các đỉnh được thăm theo phương pháp này lần lượt là E.Hình 4. Hàm f là hàm bất kỳ thực hiện các xử lý nào đó với dữ liệu có kiểu Item. thứ tự các đỉnh của cây trong hình 4. vì vậy dễ dàng cài đặt các kỹ thuật duyệt cây bởi các hàm đệ quy. Sau đây ta viết hàm đệ quy duyệt cây theo thứ tự trước: hàm Preorder.. B. . D.. } } 27 Preorder (Node<Item>* root. Ví dụ. C++ cho phép tham biến của một hàm có thể là hàm. F. Tk theo thứ tự trong.1. Giả sử cây được cài đặt bằng phương pháp sử dụng hai con trỏ: firstChild và nextSibling. B. C. trong đó Item là kiểu của dữ liệu chứa trong đỉnh của cây. Hàm này chứa một tham biến là con trỏ root trỏ tới gốc cây. G. Các kỹ thuật duyệt cây được xác định đệ quy. D. f).

void f (Item)) { Stack <Node<Item>*> S. void Preorder (Node <Item>* root. while (P ! = NULL) { f (P  data).3. ngăn xếp sẽ lưu các con trỏ trỏ tới các đỉnh. // Đẩy con trỏ P vào ngăn xếp S P = P  firstChild. S. có thể viết ra các hàm đệ quy và không đệ quy thực hiện duyệt cây theo thứ tự trong: hàm Inorder. } } } Một cách tương tự. Hàm Preorder không đệ quy: template <class Item>. P = P  nextSibling. Muốn vậy chúng ta cần sử dụng một ngăn xếp để lưu các đỉnh nằm trên đường đi từ gốc tới đỉnh đang được thăm để khi tới một đỉnh mà không đi sâu xuống được thì biết được đỉnh cha của nó mà quay lên. 4. Node <Item>* P = root while (P ! = NULL) { f (P  data). Push (P). // Khởi tạo ngăn xếp rỗng S lưu // các con trỏ. Pop (). Empty ()) { P = S. } while (! S. và duyệt cây theo thứ tự sau: hàm Postorder. // Loại con trỏ P ở đỉnh ngăn xếp. Biểu diễn và duyệt cây tổng quát 4. Push (P). S.1. P = P  firstChild.Chúng ta cũng có thể cài đặt hàm Preorder không đệ quy. Thay vì lưu các đỉnh.3. Biểu diễn cây tổng quát 28 .

Mỗi nút có một danh sách các con của nó. Với cây m-phân mà dùng mảng để lưu trữ theo cách thông thường thì rõ ràng là có rất nhiều ô trống. Có thể m được xác định trước. cách dùng mảng chỉ số cha như đã dùng với cây nhị phân khá thích hợp với cây m-phân.. trường Left_Child trỏ tới con trái nhất. 2.. Dùng mảng A để biểu diễn cây T theo nguyên tắc: A(i) = 0 nếu nút i là gốc. Cây tổng quát Có thể hiểu là cây tổng quát là cây m-phân nào đó. n. Cũng có thể dùng danh sách liên kết biểu diễn cây tổng quát. A(i) = j nếu j là cha của nút i. Dùng mảng biểu diễn cây tổng quát.Hình 4. cũng có thể m không được xác định trước. bắt đầu từ con bên trái nhất đến con bên phải nhất. Giả sử có n nút được đánh số là 1. 1. Data là trường lưu trữ thông tin của nút. 1. 2. còn trường Right_Sibling trỏ tới nút em kế cận bên phải của nút hiện tại 29 . ngoài ra. Mỗi nút có thể hình dung gồm ba trường chính: trong đó. .5. Dùng mô hình cây nhị phân với con trái nhất và nút em kế cận bên phải.. Tuy nhiên.

7. Duyệt cây tổng quát Với mỗi cách biểu diễn cây tổng quát. Với cây tổng quát 4. 5.5. có thể sử dụng các cách duyệt cây nhị phân trong mục trước cho cây tổng quát chuyển đổi. 4. có nhiều cách duyệt tương ứng. 2. ta sẽ nhận được danh sách các đỉnh theo thứ tự: 1.Hình 4. Danh sách các đỉnh của cây 4. 5.5 có được theo phương pháp duyệt trung thứ tự: 4. 3. 8. Danh sách các đỉnh của cây 4. 1. 6.6. 7. 3. với cách biểu diễn thông qua cây nhị phân với con trái nhất và nút em kế cận bên phải. 1. 1. 5. 6. 2. Hình ảnh danh sách lên kết lưu trữ cây 4. 10 2.5 có được theo phương pháp duyệt hậu thứ tự: 7. 4. 9. Chẳng hạn.2. 8. 10. 3. 9. 2. 10. 6. nếu áp dụng phương pháp duyệt tiền thứ tự. 30 . Tuy nhiên cũng có thể xây dựng riêng thủ tục duyệt cây tổng quát nhằm tăng hiệu quả của phép duyệt. 3.3.5 4. 8. 9.

Mô tả CTDL biểu diễn cây theo cách đó bằng các khai báo trong C + +. hãy viết các hàm không đệ quy duyệt cây theo thứ tự inorder và postorder.Bài tập 1. 2. 31 . Cho cây: A B a c D E F G H I J K Hãy viết ra danh sách các đỉnh khi duyệt cây theo các thứ tự preorder. Giả sử cây được biểu diễn bằng cách sử dụng hai con trỏ firstChild và nextSibling. Hãy đưa ra cách biểu diễn cây bởi mảng. 3. Bằng cách sử dụng ngăn xếp. inorder và postorder.

You're Reading a Free Preview

Tải về
scribd
/*********** DO NOT ALTER ANYTHING BELOW THIS LINE ! ************/ var s_code=s.t();if(s_code)document.write(s_code)//-->