1 ĐẠI HỌC THÁI NGUYÊN TRƯỜNG ĐẠI HỌC SƯ PHẠM BÀI TIỂU LUẬN CHỦ ĐỀ TÌM HIỂU THUẬT TOÁN, THUẬT TOÁN ĐỆ QUY VÀ THUẬT TOÁN KHÔNG ĐỆ QUY Giảng viên hướng dẫn Nguyễn Văn Trường 2 Thái Nguyên, tháng 10[.]
Trang 1ĐẠI HỌC THÁI NGUYÊN TRƯỜNG ĐẠI HỌC SƯ PHẠM
- -BÀI TIỂU LUẬN CHỦ ĐỀ:
TÌM HIỂU THUẬT TOÁN, THUẬT TOÁN ĐỆ QUY VÀ
THUẬT TOÁN KHÔNG ĐỆ QUY
Giảng viên hướng dẫn: Nguyễn Văn Trường
Trang 3Mục lục
I LỜI MỞ ĐẦU 5
II PHẦN MỞ ĐẦU 7
1 Lý do chọn đề tài 7
2 Mục tiêu của đề tài 8
3 Đối tượng nghiên cứu 8
4 Nhiệm vụ nghiên cứu 8
5 Phương pháp nghiên cứu 9
III PHẦN NỘI DUNG 9
CHƯƠNG I THUẬT TOÁN 10
1 Khái niệm 10
2 Đặc trưng của thuật toán 10
3 Các kiểu biểu diễn của thuật toán 14
4 Áp dụng thuật toán vào chương trình giáo dục phổ thông 17
CHƯƠNG II THUẬT TOÁN ĐỆ QUY 17
4 Áp dụng thuật toán đệ quy vào chương trình giáo dục phổ thông 22
CHƯƠNG III THUẬT TOÁN KHỬ ĐỆ QUY 24
IV PHẦN KẾT LUẬN 29
Trang 4DANH SÁCH CÁC TỪ VIẾT TẮT
Trang 51. LỜI MỞ ĐẦU
Cấu trúc dữ liệu (CTDL) và giải thuật là môn học đóng vai trò quan trọng trong quá trình đào tạo cử nhân các ngành khoa học máy tính và công nghệ thông
Trang 6tin Bài tiểu luận này được viết dựa trên cơ sở giáo trình “Cấu trúc dữ liệu và giảithuật”.
Chủ đề lần này của bài thảo luận của chúng em là tìm hiểu về Thuật toán, thuật toán đệ quy và thuật khử đệ quy Bài thảo luận này gồm 3 phần: Phần mở đầu, phần nội dung, và phần kết luận
Nội dung của bài thảo luận được trình bày sau đây sẽ phần nào giúp các bạn hiểu sâu sắc hơn về thuật toán, thuật toán đệ quy và các giải thuật liên quan tới nó.Trong đề tài này chúng tôi trình bày gồm có 3 chương.Mỗi chương chúng em
đã cố gắng trình bày ngắn gọn, trực tiếp vào bản chất của vấn đề, đồng thời sử dụng cài đặt tất cả các chương trình bằng ngôn ngữ lập trình C++,hy vọng sẽ mang lại sự gần gũi, dễ hiểu cho các sinh viên,mong rằng nó sẽ thực sự giúp ích cho các bạn trong quá trình nghiên cứu về đệ quy
Ở phần nội dung của bài thảo luận này sẽ gồm 3 chương:
Chương 1: Trình bày khái niệm thuật toán, các tính chất của
thuật toán, biểu diễn thuật toán Đưa ra các kiểu dữ liệu và giải thích về độ phức tạp của thuật toán
Chương 2: Trình bày khái niệm thuật toán đệ quy, ý tưởng, ví dụ,
độ phức tạp của thuật toán đệ quy và các chương trình cài đặt.
Chương 3: Trình bày khái niệm thuật toán đệ quy, ý tưởng, ví dụ,
độ phức tạp của thuật toán khử đệ quy và các chương trình cài đặt.
Bài thảo luận này sẽ giúp mọi người nâng cao kiến thức cơ bản về Tin học Bài thảo luận này chắc chắn không tránh khỏi những thiếu sót, chúng em chân thành mong nhận được ý kiến đóng góp của thầy
Trang 7Nhóm tác giả.
Trang 83 Lý do chọn đề tài.
Đối với một lập trình viên, việc học thuật toán và sử dụng chúng đúng cách sẽgiúp bạn giải quyết vấn đề một cách dễ dàng, chính xác trong thời gian ngắn nhất Vì thế thuật toán là một phần quan trọng không thể thiếu trong bộ môn
“Cấu trúc dữ liệu và giải thuật”
Chúng em chọn đề tài này vì tính quan trọng của thuật toán như đã nêu trên,
và sẽ giúp mọi người hiểu hơn
Đệ quy không những giúp người lập trình giải quyết tốt các bài toán mà còn giúp nâng cao tư duy toán, rèn luyện kỹ thuật lập trình.Tuy rằng bên cạnh giải thuật đệ quy vẫn có những giải thuật lặp khá đơn giản và hữu hiệu,chẳng hạn nhưgiải thuật lặp tính n! nhưng đệ quy vẫn có vai trò xứng đáng của nó, có những bài toán việc nghĩ ra lời giải đệ quy thuận lợi hơn nhiều so với lời giải lặp và có những giải thuật đệ quy thật sự cũng có hiệu lực cao nữa
4 Mục tiêu của đề tài.
Giúp mọi người hiểu hơn về thuật toán, cụ thể là thuật toán đệ quy và thuật toán khử đệ quy Cũng như là tìm hiểu về ý tưởng của thuật toán, cách cài đặt, ví
dụ cũng như là độ phức tạp của từng thuật toán
Nghiên cứu này phục vụ cho việc học tập môn CTDL>, cũng như là một bài tập lớn cho cả nhóm
5 Đối tượng nghiên cứu.
Đối tượng nghiên cứu bao gồm:
Thuật toán.
Thuật toán đệ quy.
Thuật toán khử đệ quy.
Trang 96 Nhiệm vụ nghiên cứu.
Việc nghiên cứu về thuật toán đóng một vai trò quan trọng trong khoa học máy tính vì máy tính chỉ giải quyết được bài toán khi đã có hướng dẫn giải rõ ràng đúng đắn Nếu giải thuật sai hoặc các bước mập mờ, không rõ ràng sẽ dẫn đến việc không giải quyết dược yêu cầu mà bài toán đặt ra
7 Phương pháp nghiên cứu.
Chúng em sử dụng phương pháp nghiên cứu tài liệu, và phân tích để tổng hợp lại những kiến thức một cách cô đọng nhất để mọi người có thể tiếp cận
Chúng em sẽ sử dụng kiến thức của môn Toán rời rạc (cụ thể là phần “quy nạp”) để áp dụng vào 1 số bài toán sử dụng thuật toán đệ quy
Trang 108. PHẦN NỘI DUNG.
CHƯƠNG I THUẬT TOÁN.
1 Khái niệm.
Thuật toán trong tiếng Anh có nghĩa là Algorithms, khái niệm đề cập đến
một quá trình được sử dụng để xử lý, tính toán hay giải quyết một vấn đề nào
đó Khái niệm thuật toán vốn được sử dụng rộng rãi trong lĩnh vực công nghệ,trong toán học, trong ngành khoa học máy tính hay thậm chí là trong kinh doanh và marketing, tuỳ thuộc vào từng điều kiện cụ thể, các thuật toán được ứng dụng theo những cách khác nhau
Trong tin học, thuật toán là một hệ thống chặt chẽ và rõ ràng các quy tắc nhằm xác định một dãy các thao tác trên những đối tượng, sao cho sau một số
hữu hạn bước thực hiện các thao tác, ta đạt được mục tiêu đã định trước
2 Đặc trưng của thuật toán.
Thuật toán được đặc trưng bởi 6 yếu tố, bao gồm:
Tính xác định.
Tính xác định của thuật toán thể hiện ở chỗ: Các thuật toán thực hiện một số bước cố định và luôn kết thúc với trạng thái chấp nhận hoặc từ chốivới cùng một kết quả Ở mỗi bước của thuật toán thì các thao tác phải rõ ràng, không gây ra sự nhầm lẫn, lẫn lộn,… Những thuật toán có kết quả ngẫu nhiên được gọi là không xác định
Ví dụ một đoạn chương trình về tính xác định:
function is_odd(n):
if n mod 2 = 1
then return true
else return false
Trang 11Đây là một thuật toán xác định vì nó được sử dụng để xem một số nhất định có phải số lẻ hay không.
Tính hữu hạn.
Một thuật toán bao giờ cũng phải dừng lại sau một số hữu hạn bước
Tức là nó sẽ bắt đầu và sau một số bước thì phải kế thúc và đưa ra kết quả như mong muốn Tính hữu hạn là tính chất dễ bị vi phạm nhất, thường do sai sót khi không trình bày
Để tránh việc lặp vô tận khi cài đặt thì các thuật toán phải có tính hữu hạn (tính dừng)
i <= n, thì biến t sẽ có giá trị là t*(i), nếu biến i > n thì sẽ trả giá trị t lại =1
Tính tổng quát.
Thuật toán cần phải có tính tổng quát khi áp dụng được cho mọi trường hợp chứ không trong trường hợp nào cụ thể cả Vì thuật toán sẽ làm việc trên nhiều kiểu dữ liệu khác nhau, trong một miền xác định và luôn dẫn đến kết quả mong muốn và cần tính tổng quát cho mọi trường hợp
Ví dụ về tính tổng quát:
Int giaipt(float a, float b, float c) {
Trang 12float delta = b*b – 4*a*c;
cout << “Phuong trinh da cho co 2 nghiem”; }
Thuật toán trên để giải phương trình bậc hai và cho biết có nghiệm hay không cho từng trường hợp của delta
Dễ hiểu đối với con người
Dễ cài đặt trên máy tính
Thông thường các thuật toán thường không đảm bảo thỏa mãn đầy đủ các tiêu chuẩn ở trên Chẳng hạn người ta thấy rằng một thuật toán sử dụngnhiều bộ nhớ thường chạy nhanh và ngược lại nếu nó sử dụng ít bộ nhớ thì hay chạy chậm
Trang 13 Tính đúng.
Thuật toán cần đảm bảo tính đúng đắn, nghĩa là sau khi đưa dữ liệu vào
nó có thể hoạt động và đưa ra kết quả như ý muốn Tuy nhiên, đây là tính chất khó đạt tới nhất Điều này tương tự như khi ta giải một bài toán, tất cả chúng ta đều mong đưa ra đáp án đúng, nhưng không phải lúc nào cũng đạtđược Việc chứng minh tính đúng đắn của thuật toán rất quan trọng Đối với nhiều vấn đề, không thể khẳng định độ tin cậy của một thuật toán cho đến khi nó đưa ra đầu ra chính xác cho mỗi đầu vào hợp lệ
Ví dụ về tính đúng: Cho một dãy A[1…n], xét x xem x có thuộc vào dãy A[1…n]?
Void timkiem(int a[], int x) {
for (i -1;i <= n; i++)
if (a[i] == x)
cout << “Co xuat hien”;
else cout << “Khong xuat hien”;
Đây là một đoạn chương trình nhìn qua thì tưởng đúng nhưng thực chất
là sai, vì tính không rõ ràng, nó xuất hiện cả hai kết quả Dẫn đến không cótính đúng
Trang 14 Tính có đại lượng vào và ra.
Ở bài toán nào khi sử dụng đến thuật toán cũng cần đảm bảo các đại lượng vào và ra Đại lượng vào mà ta thường gọi là dữ liệu vào (input), các
dữ liệu vào thường lấy từ một tập xác định cho trước
Sau khi thuật toán chay xong thì cần có một dữ liệu ra (output)
Ví dụ về tính có đại lượng vào và ra:
VD: Tìm phần tử lớn nhất trong mảng A:
Input: Mảng A gồm n số nguyên
Output: GTLN của mảng A
3 Các kiểu biểu diễn của thuật toán.
Các phương pháp biểu diễn thuật toán phổ biến:
Ngôn ngữ tự nhiên
Trong cách biểu diễn thuật toán theo ngôn ngữ tự nhiên, người ta
sử dụng ngôn ngữ thường ngày để liệt kê các bước của thuật toán Phương pháp biểu diễn này không yêu cầu người viết thuật toán cũng như người đọc thuật toán phải nắm các quy tắc Tuy vậy, cách biểu diễn này thường dài dòng, không thể hiện rõ cấu trúc của thuật toán, đôi lúc gây hiểu lầm hoặc khó hiểu cho người đọc
Ví dụ:
Trang 15 Sơ đồ khối (flowchart).
Sơ đồ khối là một công cụ trực quan để diễn đạt các thuật toán Biểu diễn thuật toán bằng lưu đồ sẽ giúp người đọc theo dõi được sựphân cấp các trường hợp và quá trình xử lý của thuật toán Phương pháp lưu đồ thường được dùng trong những thuật toán có tính rắc rối, khó theo dõi được quá trình xử lý
Ðể biểu diễn thuật toán theo sơ đồ khối, ta cần lưu ý các thao tác với nhau
Thao tác chọn lựa: Thao tác chọn lựa được biểu diễn bằng một hình thoi, bên trong chứa biểu thức điều kiện
Thao tác xử lý: Thao tác xử lý được biểu diễn bằng một hình chữnhật, bên trong chứa nội dung xử lý
Trang 16 Đường đi: Đường đi được biểu diễn bằng các mũi tên, chỉ hướng đi.
Ví dụ:
Mã giả
Mọi ngôn ngữ lập trình đều có những thao tác cơ bản là xử lý, rẽ nhánh và lặp Dùng mã giả vừa tận dụng được các khái niệm trong ngôn ngữ lập trình, vừa giúp người cài đặt dễ dàng nắm bắt nội dungthuật toán Tất nhiên là trong mã giả ta vẫn dùng một phần ngôn ngữ
tự nhiên
Ví dụ:
if Delta > 0 then begin
Trang 17x1=(-b-sqrt(delta))/(2*a)x2=(-b+sqrt(delta))/(2*a)xuất kết quả : phương trình có hai nghiệm là x1 và x2end
else
if delta = 0 thenxuất kết quả : phương trình có nghiệm kép là -b/(2*a)else {trường hợp delta < 0 }
xuất kết quả : phương trình vô nghiệm
Ngôn ngữ lập trình
Vì ngôn ngữ lập trình có ngữ nghĩa được quy định rõ ràng, nên
nó cho chép biểu diễn giải thật toán một cách chính xác Bài thảo luận này sử dụng ngôn ngữ lập trình C++ để biểu diễn thuật toán
4 Áp dụng thuật toán vào chương trình giáo dục phổ thông.
CHƯƠNG TRÌNH GIÁO DỤC PHỔ THÔNG MÔN TIN HỌC (Ban hành kèm theo Thông tư số 32/2018/TT-BGDĐT ngày 26 tháng 12 năm
2018 của Bộ trưởng Bộ Giáo dục và Đào tạo)
Chương trình môn Tin học ở cấp trung học phổ thông thể hiện sự phân hoá sâu hơn về định hướng nghề nghiệp Do vậy, chương trình có các yêu cầu cần đạt chung về năng lực tin học bắt buộc đối với mọi học sinh và có các yêu cầu bổ sung riêng tương ứng với học sinh chọn định hướng Tin học ứng dụng hoặc Khoa học máy tính
Giúp học sinh có những hiểu biết cơ bản về hệ thống máy tính, một số
kĩ thuật thiết kế thuật toán, tổ chức dữ liệu và lập trình; củng cố và phát triển hơn nữa cho học sinh tư duy giải quyết vấn đề, khả năng đưa ra ý tưởng và chuyển giao nhiệm vụ cho máy tính thực hiện
Trang 18CHƯƠNG II THUẬT TOÁN ĐỆ QUY.
1 Tổng quan về thuật toán đệ quy.
Đệ quy (Recursion) là một trong những giải thuật quen thuộc trong lập trình, hay rộng hơn là trong toán học (thường được gọi với cái tên khác là
“quy nạp”) Có một số bài toán, bắt buộc người giải phải sử dụng đệ quy mới giải quyết được, chẳng hạn như duyệt cây
Mô tả đệ quy được hiểu là một đối tượng được mô tả thông qua chính nó
Một bài toán mang tính chất đệ quy khi nó có thể được phân ra thành các bài toán nhỏ hơn nhưng vẫn mang cùng tính chất với bài toán ban đầu Các bài toán nhỏ lại được phân ra thành các bài toán nhỏ hơn nữa theo cùng như tính chất đó
Để tránh việc lặp vô tận khi cài đặt TTĐQ, hàm đệ quy cần có tính dừng: Nếu gặp 1 điều kiện nào đó, nó cần phải dừng lại việc tự gọi lại chính mình
2 Một số bài toán cơ bản của thuật toán đệ quy.
Bài 1: Tìm phần tử Fibonacci (bài toán Fibonacci).
Ý tưởng: Số tiếp theo trong dãy số sẽ được tính bằng cách cộng 2 số
trước với nhau
Trang 19Cài đặt chương trình:
Kèm link driver ở cuối
Ví dụ:
Chúng ta sẽ diễn giải cách chạy của hàm đệ quy trong bài toán
Fibonancci qua từng bước:
Bước 1: Nếu n = 0, hoặc n = 1; thì giá trị của fibo(int n) sẽ trả về 1.Bước 2: Không thì giá trị của fibo (int n) sẽ luôn được gọi bằng tổng giá trị của số ở vị trí (n-1) + số ở vị trí (n-2)
Hàm fibo() có điều kiện dừng chính là n = 0, hoặc n =1
Độ phức tạp:
Bài 2: Tính giai thừa bằng thuật toán đệ quy.
Ý tưởng: Giai thừa của một số là số đó nhân với số trước đó
Trang 20Bước 2: Không thì giá trị của giaithua(int n) sẽ luôn được gọi trả về giátrị của số n * giaithua(n-1).
Hàm giaithua() có điều kiện dừng chính là n =1
Độ phức tạp:
Bài 3: Tính số mũ của một số bằng thuật toán đệ quy.
Ý tưởng: Số mũ n của một số là n lần số đó nhân với nhau.
Bước 1: Nếu n = 0; thì giá trị của somu(int n,int k) sẽ trả về 1
Bước 2: Nếu n = 1; thì giá trị của somu(int n,int k) sẽ trả về n
Bước 3: Không thì giá trị của somu(int n,int k) sẽ luôn được trả về giá trị của số n*somu(n,k-1)
Hàm somu() có điều kiện dừng chính là n=0, n =1
Trang 21Độ phức tạp:
Bài 4: Tìm UCLN của hai số bằng thuật toán đệ quy.
Ý tưởng: Tìm UCLN của hai số bằng cách dùng thuật toán Euclid.
Chia lấy số dư của số lớn cho số bé, sau đó lấy số chia chia tiếp cho số
dư (của phép tính trước) Nếu kết quả bằng 0, thì số chia là UCLN, còn không thì số dư cuối cùng sẽ là UCLN
m = 0 => n là uclnn%m == 0 => m là uclnn%m = k; m%k = l, k%l = 0 => l là ucln
Bước 1: Nếu m = 0; thì giá trị của UCLN(int n,int m) sẽ trả về n
Bước 2: Nếu n%m == 0; thì giá trị của UCLN(int n,int m) sẽ trả về m.Bước 3: Không thì giá trị của UCLN(int n,int m) sẽ luôn được trả về giátrị của số ucln (n,n%m)
Hàm UCLN() có điều kiện dừng chính là m=0, n%m =0
Trang 22Độ phức tạp:
3 Ưu điểm và nhược điểm của thuật toán đệ quy.
Ưu điểm:
Công cụ mạnh, diễn đạt tư duy rất rõ ràng, chặt chẽ
Ngắn gọn, có khả năng định nghĩa một tập hợp rất lớn các đối tượng bằng một số câu lệnh hữu hạn
Làm cho chương trình trông đẹp mắt, dễ đọc, dễ hiểu và chương trình được nêu bật rõ ràng hơn
Nhược điểm:
Đệ quy tốn bộ nhớ nhiều hơn khi không đệ quy vì mỗi lần gọi đệ quy lại cần thêm một vùng nhớ mới trong khi vùng nhớ cũ vẫn được duy trì
Tốc độ thực hiện chương trình chậm hơn khi không đệ quy
4 Áp dụng thuật toán đệ quy vào chương trình giáo dục phổ thông.
Theo CTGDPT 2018 môn Tin học, chuyên đề học tập sẽ được đi theo hai định hướng:
Định hướng Tin học ứng dụng
Định hướng Khoa học máy tính
Chúng ta sẽ đi cụ thể vào định hướng KHMT, lớp 11 sẽ có chuyên đề: Thực hành thiết kế thuật toán theo kĩ thuật Đệ quy Ở chuyên đề này, mục tiêu là: Giúp học sinh có khả năng thiết kế thuật toán theo kĩ thuật Đệ quy
Cụ thể chuyên đề này có những bài toán cơ bản như sau mà học sinh cần hiểu và có thể viết được chương trình:
Trình bày được tính đệ quy trong một vài định nghĩa sự vật, sự việc
Trang 23 Xác định được phần cơ sở và phần đệ quy trong mô tả đệ quy
Ứng dụng được kĩ thuật Đệ quy trong thiết kế một vài thuật toán như:
Tính an (hoặc n!)
Tìm phần tử thứ n của dãy Fibonaci
Bài toán Tháp Hà Nội
Viết được chương trình sử dụng kĩ thuật Đệ quy cho một vài bài toán đơn giản
Nhận biết được tính ưu việt của kĩ thuật Đệ quy trong định nghĩa
sự vật,mô tả và thiết kế thuật toán
Ở bài thảo luận này thì chúng em sẽ chỉ đưa ra những phần cài đặt chương trình cũng như ý tưởng thuật toán, biểu diễn, và cài đặt chương trình cho 3 bài toán ứng dụng ở trên Các khái niệm về thuật toán thì chúng
em đã nêu ra ở trên
cơ bản của thuật toán Đệ quy).
Bài toán tìm phần tử thứ n của dãy Fibonaci (đã nêu kèm ở trên)
(phần Một số bài toán cơ bản của thuật toán Đệ quy).
Bài toán Tháp Hà Nội:
Ý tưởng:
Nếu đã biết cách chuyển N - 1 đĩa từ cột A sang cột B, ta chỉ cần
chuyển đĩa thứ N (đĩa cuối cùng) từ cột A sang cột C, rồi chuyển N - 1 đĩa
từ cột B sang cột C
Giải thuật không còn đệ quy khi chỉ có 1 đĩa, vì ta chuyển trực tiếp từ cột A sang cột C luôn mà không cần thông qua cột B
Biểu diễn: