Thuật toán Giới thiệu thuật toán và đánh giá thuật toán Xét bài toán tìm phần tử lớn thứ k trong mảng Xét bài toán tìm phần tử lớn thứ k trong mảng Sắp xếp giảm dần toàn mảng Sắ
Trang 1CẤU TRÚC DỮ LIỆU
CẤU TRÚC DỮ LIỆU
VÀ GIẢI THUẬT
Lý thuyết
Trang 4Thuật toán
Giới thiệu thuật toán và đánh giá thuật toán
Xét bài toán tìm phần tử lớn thứ k trong mảng
Xét bài toán tìm phần tử lớn thứ k trong mảng
Sắp xếp giảm dần toàn mảng
Sắp xếp k phần tử đầu tiên và chèn dầnp p p
Chương 7 giới thiệu 1 thuật toán đủ tốt
Xét bài toán trò chơi ô chữ
Trang 5Thuật toán
¾ Có thể đánh giá dựa trên thời gian chạy
¾ Làm thế nào để đánh giá thời gian chạy của g g ạy một chương trình?
¾ Đánh giá thời gian chạy không thực sự dựa g g ạy g ự ự ự trên mã lệnh của chúng.
Trang 8Đệ quy và giải thuật đệ quy
Khái niệm : 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 chính nó.
Trang 9Đệ quy và giải thuật đệ quy
Giải thuật đệ quy và thủ tục đệ quy :
Nếu lời giải của bài toán T được thực hiện bằng lời giải của bài toán T’ có dạng giống T, thì đó là một lời giải
đệ quy Giải thuật tương ứng với lời giải như vậy gọi là giải thuật đệ quy Điểm chú ý là T’ phải “nhỏ hơn” T
giải thuật đệ quy Điểm chú ý là T phải nhỏ hơn T
Đệ quy gián tiếp (indirectly rescursive) : Chứa lời gọi
Đệ quy gián tiếp (indirectly rescursive) : Chứa lời gọi
Trang 10Đệ quy và giải thuật đệ quy
Thiết kế giải thuật đệ quy :
Hàm N!
Hàm Fibonaci
F(n) = 1 nếu n<=2( )
F(n) = F(n-2) + F(n-1) if n>2
Viết một số theo thứ tự ngược lại Ví dụ : ộ ự g ợ ạ ụ
2893 được viết lại là 3982
Trang 11Đệ quy và giải thuật đệ quy
1 void printOut( int n ) // In số n không âm
Trang 12Đệ quy và giải thuật đệ quy *
Bài toán “Tháp Hà Nội”
Phát biểu bài toán :
Phát biểu bài toán :
Có 3 cọc, cần chuyển đĩa từ cọc A sang cọc C
Cọc trung gian Bọ g g
Mỗi lần chỉ được chuyển 1 đĩa
Không bao giờ có trường hợp đĩa to ở trên đĩa nhỏ
Tất cả các đĩa có kĩch cỡ khác nhau
Trang 13Đệ quy và giải thuật đệ quy *
Đệ quy quay lui (back tracking):
Bài toán tổ hợp chỉnh hợp
Bài toán tổ hợp, chỉnh hợp
Bài toán người mua hàng
Bài toán tám quân hậu
Bài toán tám quân hậu
Trang 14Đánh giá thuật toán
Thuật toán đòi hỏi bao nhiêu tài nguyên về không gian và thời gian?
Làm sao để ước lượng thời gian chạy của một chương trình?
Trang 15Các định nghĩa
Định nghĩa 2.1.
T(N) = O(f(N)) nếu có các hằng số dương c
T(N) = O(f(N)) nếu có các hằng số dương c
và n0 sao cho T(N) ≤ cf(N) khi N ≥ n0.
Trang 17Đánh giá thuật toán
Khi T(N) = O(f(N)), là T(N) tăng với tỉ
lệ không nhanh hơn f(N); do vậy f(N)
lệ không nhanh hơn f(N); do vậy f(N)
là biên trên của T(N)
Do điều này ngụ ý rằng f(N) =
Do điều này ngụ ý rằng f(N) =
Ω(T(N)), chúng ta nói rằng T(N) là biên dưới của f(N)
dưới của f(N).
Trang 18Đánh giá thuật toán
O(N2) đều đúng về mặt kỹ thuật nhưng
= O(N2) đều đúng về mặt kỹ thuật nhưng lựa chọn O(N2)là đáp án tốt nhất
Trang 19Các quy tắc
Quy tắc 1.
Nếu T1(N) = O(f(N)) và T2(N) = O(g(N)) thì
Nếu T1(N) O(f(N)) và T2(N) O(g(N)), thì
(a) T1(N) + T2(N) = O(f(N) + g(N)) ( hay
Trang 20 độ phức tạp đa thức , O(P(n)), với P là đa thức bậc cao (từ 2 trở lên) Chẳng
h hư á th tá tí h t á ới ả hiề hiề (tí h đị h thứ
hạn như các thao tác tính toán với mảng nhiều chiều (tính định thức ma trận)
độ phức tạp logarit , O(logn) (chú ý: bậc của nó thấp hơn so với O(n))
Chẳng hạn thuật toán Euclid để tìm ước số chung lớn nhất
Chẳng hạn thuật toán Euclid để tìm ước số chung lớn nhất
độ phức tạp hàm bậc 2 , O(N 2 )
Trang 22Bài toán tổng dãy con lớn nhất
Cho các số nguyên (có thể âm) A1, A2, ,
Trang 23Bài toán tổng dãy con lớn nhất
Trang 24Cách tính thời gian chạy
Viết đoạn chương trình tính :
int sum( int n )
Trang 25Cách tính thời gian chạy
Phân tích :
Các khai báo không chiếm thời gian
Các dòng 1 và 4 được tính mỗi dòng một đơn vị thời gian
Dòng 3 được tính bốn đơn vị thời gian thực hiện (hai phép nhân, một phép cộng, và một phép gán) và dòng này được thực hiện N lần, nâng
tổng thời gian chạy lên 4N đơn vị
Dòng 2 Nn chứa thời gian khởi tạo i, kiểm tra i < N , và tăng i Thời
gian của các thao tác này gồm 1 cho việc khởi tạo, N + 1 cho các kiểm
tra, và N cho các phép tăng, tổng cộng là 2N + 2
Chúng ta còn chưa kể đến thời gian gọi hàm và trả về giá trị nên tổng cộng thời gian lên đến 6N + 4 ộ g g
Trang 26Các quy tắc
Thời gian chạy của một vòng lặp for là thời gian chạy
của các lệnh bên trong vòng lặp (kể cả các phép kiểmtra) nhân với số lần lặp
Trang 27Thời gian chạy không bao giờ vượt quá thời gian chạy
phép kiểm tra điều kiện cộng với thời gian chạy lớn nhất
của S1 và S2
Trang 28Một số trường hợp đệ quy
Ví dụ, hàm sau đây thực ra chỉ là một vòng lặp đơn
giản và là O(N ):
long factorial(int n){
Trang 30 “Đừng tính bất cứ cái gì quá một lần”
Trang 31Các thuật toán cho bài tổng dãy con lớn nhất
Ví dụ trong file MaxSumTest.cpp
8 for (int i = 0; i < a.size(); i++)
9 for (int j = i; j < a size(); j++)
9 for (int j = i; j < a.size(); j++)
Trang 32Các thuật toán cho bài tổng dãy con lớn nhất – Thuật toán 1
Đánh giá thuật toán 1
N
i j
j
i k
Trang 33Các thuật toán cho bài tổng dãy con lớn nhất – Thuật toán 1
Tiếp theo :
∑−
=
− +
−
= +
−
1
2
) )(
1 (
) 1 (
N i j
i N i
N i
−
=
− +
N i
N i
1 (
2
) )(
1 (
1 3
2
2 3
2
) 1 (
) 2
3 (
6
) 1 2
)(
1 (
2 1
1 ) 2 3
( 2
1 )
2
3 (
2 1
2 1
2 1
1 2
N N
N N
N N
N N
N
N N
i N
+
+ +
− + +
=
+ +
+ +
2 2
2 6
Trang 34Các thuật toán cho bài tổng dãy
con lớn nhất – Thuật toán 2
Chúng ta đưa ra cải tiến thuật toán 1 bằng cách loại
Trang 35Các thuật toán cho bài tổng dãy con lớn nhất – Thuật toán 3
Thuật toán 3 :
Tổng lớn nhất các dãy con có thể ở một trong ba vị trí : g y ộ g ị
Có thể trong nửa trái hay nửa phải của đầu vào, hoặc nằm ở giữa, thuộc về cả hai nửa
Hai trường hợp đầu có thể giải được bằng đệ quy
Trường hợp cuối, tìm tổng lớn nhất trong nửa đầu bao gồm
cả phần tử cuối cùng của nửa đầu và tìm tổng lớn nhất
cả phần tử cuối cùng của nửa đầu, và tìm tổng lớn nhất
trong nửa cuối bao gồm cả phần tử đầu tiên trong nửa cuối Hai tổng này được cộng với nhau
Trang 36Các thuật toán cho bài tổng dãy
con lớn nhất – Thuật toán 3
14 int center = ( left + right ) / 2;
15 int maxLeftSum = maxSumRec( a, left, center );
16 int maxRightSum = maxSumRec( a, center + 1, right );
17
18 int maxLeftBorderSum = 0, leftBorderSum = 0;
19 for( int i = center; i >= left; i )
Trang 37Các thuật toán cho bài tổng dãy con lớn nhất – Thuật toán 3
Thuật toán 3 :
25
26 int maxRightBorderSum = 0, rightBorderSum = 0;
27 for( int j = center + 1; j <= right; j++ )
Trang 38Các thuật toán cho bài tổng dãy con lớn nhất – Thuật toán 3
Đánh giá thuật toán 3 :
Trang 39Các thuật toán cho bài tổng dãy con lớn nhất – Thuật toán 4
Trang 40Thuật toán Euclid