SỞ GIÁO DỤC VÀ ĐÀO TẠO THANH HOÁTRƯỜNG THPT BA ĐÌNH NGA SƠN SÁNG KIẾN KINH NGHIỆM SỬ DỤNG GIẢI THUẬT SẮP XẾP GIÚP HỌC SINH GIẢI CÁC BÀI TOÁN TRONG LẬP TRÌNH THEO ĐỊNH HƯỚNG PHÁT TRIỂN
Trang 1SỞ GIÁO DỤC VÀ ĐÀO TẠO THANH HOÁ
TRƯỜNG THPT BA ĐÌNH NGA SƠN
SÁNG KIẾN KINH NGHIỆM
SỬ DỤNG GIẢI THUẬT SẮP XẾP GIÚP HỌC SINH GIẢI CÁC BÀI TOÁN
TRONG LẬP TRÌNH THEO ĐỊNH HƯỚNG PHÁT TRIỂN NĂNG LỰC
Họ và tên: Vũ Thị Huệ
Chức vụ: Giáo Viên
SKKN thuộc môn: Tin Học
THANH HOÁ, NĂM 2021
Trang 2Mục lục
1 Mở đầu 1
1.1 Lý do chọn đề tài 1
1.2 Mục đích nghiên cứu 1
1.3 Đối tượng nghiên cứu 1
1.4 Phương pháp nghiên cứu 1
1.5 Những điểm mới của sáng kiến 2
2 Nội dung sáng kiến kinh nghiệm 2
2.1 Cơ sở lý luận của vấn đề 2
2.2 Thực trạng của vấn đề trước khi áp dụng sáng kiến kinh nghiệm 3
2.3 Giải pháp và tổ chức thực hiện 3
2.4 Hiệu quả của đề tài nghiên cứu 19
3 Kết luận và đề xuất……… ………20
3.1 Kết luận……….………… ……… ……… 20
3.2 Đề Xuất ……….………… 20
Tài liệu tham khảo
Danh mục các đề tài SKKN
Phụ Lục
Trang 31 Mở đầu
1.1 Lý do chọn đề tài.
Sắp xếp( Sort) hiểu tổng quát là quá trình tuyển lựa, bố trí sắp đặt lại vị trícác đối tượng dữ liệu theo một trật tự nhất định Sắp xếp đóng vai trò rất quantrọng trong cuộc sống nói chung và trong Tin Học nói riêng Ý nghĩa và côngdụng của sắp xếp là giúp đơn giản hóa việc tìm kiếm các phần tử trong khối dữliệu đã được sắp xếp Thử hình dung xem, một cuốn từ điển, nếu các từ khôngđược sắp xếp theo một trật tự, sẽ khó khăn như thế nào trong việc tra cứu các từ.Theo nhà khoa học D.Knuth thì có tới 40% thời gian tính toán của máy tính làdành cho việc sắp xếp Như vậy sắp xếp là công việc thường hay sử dụng tronglập trình, nó cũng là thao tác cơ bản và quan trọng trong xử lý dữ liệu [5]
Trong quá trình giảng dạy trên lớp cũng như bồi dưỡng cho học sinh mũinhọn, tôi luôn phải sử dụng nhiều tới các kỹ thuật sắp xếp để giải các bài toán cóứng dụng của thuật toán sắp xếp
Tuy nhiên trên thực tế qua các tài liệu nghiên cứu các tác giả đều chưa tậphợp tổng hợp các thuật toán cũng như các kỹ thuật cho thuật toán sắp xếp nóichung đầy đủ nhất, chủ yếu đề cập đến các thuật toán sắp xếp tiêu biểu như nổibọt hay sắp xếp nhanh
Trong đề tài sáng kiến kinh nghiệm lần này tôi mạnh dạn trình bầy về cácthuật toán đến chương trình đề sắp xếp dữ liệu đã được đưa vào bộ nhớ chính.Tôi đã áp dụng để truyền đạt cho các học sinh của mình, thu được các tiết họcthực sự lý thú và có hiệu quả
1.2 Mục đích nghiên cứu.
- Mục đích nghiên cứu của sáng kiến này tôi muốn trình bầy làm rõ về các thuật
toán sắp xếp để ứng dụng vào giải các bài toán ở mức độ THPT
- Nắm vững về cấu trúc cú pháp và hoạt động của các giải thuật sắp xếp
- Luyện cho học sinh kỹ năng viết, lựa chọn sử dụng các kỹ thuật sắp xếp linhhoạt khi lập trình
- Học sinh biết vận dụng kiến thức về giải thuật sắp xếp giải quyết các vấn đềthực tiễn, phát huy những suy nghĩ tích cực, tư duy sáng tạo Huy động tiềmnăng của học sinh, góp phần hình thành năng lực giải quyết vấn đề cho học sinh
1.3 Đối tượng nghiên cứu.
- Sử dụng linh hoạt các kỹ thuật của giải thuật sắp xếp dữ liệu khi giải bài toántrên máy tính trong chương trình phổ thông một cách khoa học và hiệu quả nhất
1.4 Phương pháp nghiên cứu.
Khi nghiên cứu và áp dụng đề tài này tôi đã sử dụng các phương phápnghiên cứu:
- Phương pháp nghiên cứu xây dựng cơ sở lý thuyết, qua các văn bản chủ trươngcủa Đảng, chính sách pháp luật của nhà nước về giáo dục và đào tạo trongchương trình phổ thông
- Phương pháp điều tra khảo sát thực tế, thu thập thông tin và xử lý số liệu Đảmbảo tính chính xác của thực trạng, hiệu quả của vấn đề nghiên cứu và rút ranhững kết luận quan trọng
Trang 4- Phương pháp thống kê xử lý dữ liệu phân tích tổng hợp, thu thập thông tin từnhiều nguồn tài liệu.
1.5 Những điểm mới của sáng kiến.
- Sáng kiến này đề cập đến những khía cạnh khác nhau của các kỹ thuật sắp xếp
dữ liệu Từ đó đánh giá thời gian thực thi cũng như dung lượng bộ nhớ cấp phátcủa mỗi kỹ thuật sắp xếp Người lập trình có thể chọn và áp dụng thuật toán sắpxếp phù hợp với mỗi yêu cầu bài toán và dữ liệu đặt ra
- So với sáng kiến kinh nghiệm hoàn thành trong năm học 2019- 2020, năm nay trong sáng kiến này tôi đã nghiên cứu, phân tích, minh họa và trình bầy thêm về
kỹ thuật sắp xếp theo giải thuật chèn và giải thuật sắp xếp bằng đếm phân phối Thu được kết quả cao khi áp dụng giải các bài toán phổ thông và trong bồi dưỡng mũi nhọn
2 Nội dung sáng kiến kinh nghiệm
2.1 Cơ sở lý luận của sáng kiến kinh nghiệm.
Theo nhà khoa học D.Knuth đã nghiên cứu và chứng minh thì 40% thờigian tính toán của máy tính là dành cho sắp xếp Không phải ngẫu nhiên thuậttoán sắp xếp nhanh( Quick Sort) được bình chọn là một trong 10 thuật toán tiêubiểu của thế kỷ XX [5] Trong các chương trình giảng dạy Tin Học ở các cấphọc nói chung việc sắp xếp dữ liệu luôn được đề cập, trong Tin Học lớp 10 vàlớp 11 các em học sinh được học từ thuật toán đến chương trình để sắp xếp cácphần tử của mảng theo thứ tự tăng dần hoặc giảm dần là một ví dụ rất bổ ích choviệc nắm vững các phép xử lý mảng [2] Tuy nhiên thuật toán sắp xếp chủ đạotrong sách giáo khoa Tin Học lớp 10 và lớp 11 đưa ra là thuật toán sắp xếp bằngtráo đổi ( Exchange Sort) hay còn có tên gọi khác là sắp xếp nổi bọt( BubbleSort) thích hợp với các bài toán cơ sở có dữ liệu nhỏ [1] Khi giải các bài toánvới dữ liệu lớn hơn, yêu cầu độ phúc tạp nhỏ, cần thời gian chạy ít hơn, tôi đãtìm hiểu đến các thuật toán sắp xếp khác nhau để phù hợp cho mỗi bài toán đặt
ra và tôi sẽ trình bầy trong sáng kiến kinh nghiệm này
Bên cạnh đó, cá nhân tôi nhận thức về tầm quan trọng của việc tăngcường đổi mới dạy học Bộ giáo dục và đào tạo đã tập trung chỉ đạo thông quanghị quyết Hội nghị trung ương 8 khóa XI về việc đổi mới căn bản, toàn diện
giáo dục và đào tạo nêu rõ: ” Tiếp tục đổi mới mạnh mẽ phương pháp dạy học
và học theo phương pháp hiện đại, phát huy tính tích cực, chủ động sáng tạo và vận dụng kiến thức, kỹ năng của người học, khắc phục lối truyền thụ áp đặt một chiều, ghi nhớ máy móc Tập trung dạy cách học, cách nghĩ, khuyến khích tự học, tạo cơ sở để người học tự cập nhật và đổi mới trí thức, kỹ năng phát triển năng lực Chuyển từ học trên lớp sang tổ chức hình thức học tập đa dạng, chú ý các hoạt động đa dạng, ngoại khóa, nghiên cứu khoa học Đẩy mạnh ứng dụng công nghệ thông tin và truyền thông trong dạy học ”
Hiện nay trong các tài liệu về các ngôn ngữ lập trình rất phong phú và đadạng Việc đưa ra hệ thống các bài tập có tính phân bậc để luyện kỹ năng chocác em hoc sinh giúp các em dễ dàng nắm bắt nội dung của bài học mà còn địnhhướng và phát triển tư duy cho các em về khả năng ngôn ngữ lập trình, linh hoạt
Trang 5và hình thành năng lực tích cực, thiết thực cho các em Xây dựng cơ sở cả về lýthuyết lẫn vận dụng, đem lại hiệu quả cao cho người học và người dạy
2.2 Thực trạng của vấn đề trước khi áp dụng sáng kiến kinh nghiệm.
Về tinh thần thái độ của các em hoc sinh tại trường THPT Ba Đình
tôi thấy rằng các em nhận thức được vai trò lớn lao của ứng dụng công nghệthông tin trong “ Cách mạng công nghiệp 4.0” hiện nay, các em rất hào hứng,tích cực xây dựng các ý tưởng để giải các bài toán trên máy tính Thích đượclắng nghe quy trình để làm ra được các sản phẩm phần mềm mà thực tế các emđang sử dụng, điều đó kích thích được niềm say mê học lập trình của các em
Trong chương trình Tin Học THPT tại Nga Sơn, Lập trình Pascal là mônhọc khó, hầu hết các học sinh đều chưa được học và làm quen ở dưới cấp hainên các em tỏ ra rất lúng túng khi lựa chọn thuật toán, khó khăn trong việc diễnđạt các câu lệnh, cú pháp để viết chương trình
Khi dạy học trên lớp, đặc biệt việc bồi dưỡng cho các học sinh mũi nhọn,khi giải về các bài toán cần sử dụng đến thuật toán sắp xếp, nếu các em chỉ sửdụng thuật toán sắp xếp như sách giáo khoa đưa ra là sắp xếp nổi bọt sẽ gặpnhiều khó khăn để sử lý cả về số liệu lẫn thời gian chạy chương trình Cũng nhưkhó khăn khi giải các bài toán có liên quan Chương trình sẽ không kiểm trađược hết các Text đề ra và kết quả sẽ không cao Vì vậy tôi đã mạnh dạn áp dụng
đề tài:
“ SỬ DỤNG GIẢI THUẬT SẮP XẾP GIÚP HỌC SINH GIẢI CÁC BÀI TOÁN TRONG LẬP TRÌNH THEO ĐỊNH HƯỚNG PHÁT TRIỂN NĂNG LỰC ”
Để đánh giá một giải thuật sắp xếp thường dựa vào các thông số sau:
Dung lượng bộ nhớ sử dụng (Cm)
Thời gian thực thi (Ct): Bao gồm 2 thông số phụ:
a) Số lần so sánh (C)b) Số lần đổi chỗ (M) Trong các giải thuật của sáng kiến này chúng ta chỉ đánh giá về thời gian thựcthi còn dung lượng bộ nhớ sử dụng của các giải thuật thì gần như nhau
Trong sáng kiến kinh nghiệm lần này tôi sẽ trình bầy về các giải thuật sắp xếptiêu biểu cùng các ví dụ minh họa
2.3.1.2 Phân loại giải thuật sắp xếp
2.3.1.2.1 Giải thuật chèn: Giải thuật chèn được chia thành 2 loại
a Giải thuật chèn trực tiếp ( Straightinsertion)
Trang 6- Nguyên lý giải thuật: Cho một mảng gồm n phần a(1), , a(n) ta luôn có thểchia thành 2 phần: Phần có thứ tự và phần chưa có thứ tự.
Ban đầu ta có a(1) là phần tử thứ tự Ta tìm chỗ để chèn a(2) vào phần tử
có thứ tự, sau đó tiếp tục chèn a(3) vào vv cho đến phần tử cuối cùng để cómột mảng có thứ tự theo chiều tăng hoặc giảm
- Phân tích đánh giá : Nếu sử dụng giải thuật chèn trực tiếp thì
b Giải thuật chèn chia đôi ( Binaryinsertinon )
- Nguyên lý giải thuật: Giải thuật này là giải thuật chèn trực tiếp được cải tiếnbằng cách kiểm tra phần tử của mảng và cứ chia đôi cho tới khi tìm thấy vị tríchèn vào vì thế nên người ta gọi giải thuật này là giải thuật chèn chia đôi haycòn gọi là giải thuật nhị phân
- Giải thuật này tốt hơn giải thuật trước vì số lần so sánh ít hơn
Ví dụ: Chương trình sử dụng giải thuật chèn để sắp xếp từ nhỏ đến lớn các phần
Trang 72.3.1.2.2 Giải thuật chọn trực tiếp ( Straightselection)
- Nguyên lý giải thuật Chọn phần tử có khóa nhỏ nhất, đổi chỗ của nó với phần
tử thứ nhất a1 Tiếp tục thực hiện thao tác này trước tiên cho n-1 phần tử còn lạisau đó với n-2 phần tử cho tới khi còn lại một phần tử là phần tử lớn nhất[4].Với cách thức như trên, sau mỗi lần chọn thì kích thước của của mảng cần sắpxếp sẽ giản dần
- Phân tích đánh giá: Nếu sử dụng giải thuật chọn trực tiếp thì:
+ C = n2/2
+ Mmin = 3(n-1)+ Mmax = 3(n-1)+ n2/2+ Mavg = n ln(n)
2.3.1.2.3 Giải thuật đổi chỗ
a Giải thuật nổi bọt ( Buble sort )
- Nguyên lý giải thuật: Giải thuật nổi bọt dựa trên nguyên lý so sánh và đổi chỗliên tiếp các cặp phần tử đứng kề nhau cho tới khi tất cả các phần tử được sắpxếp theo thứ tự Ta duyệt mảng nhiều lần và mỗi lần thực hiện thì đẩy phần tửnhỏ nhất của phần còn lại qua đầu bên trái của mảng Ví dụ giả sử có mảng sau:
- Giải thuật này tương đối tốt và dễ hiểu nên thường được sử dụng đối với n nhỏ
b Giải thuật rung ( Sshakersort )
- Nguyên lý giải thuật: Giải thuật rung là giải thuật cải tiến của giải thuật nổibọt Đối với giải thuật nổi bọt thì mỗi lần ta chỉ đẩy được 1 phần tử vào mảng đãsắp thứ tự Người ta đã cải tiến để có thể mỗi lần duyệt thì có thể tìm một đoạnmảng đã có thứ tự để đưa đoạn đó vào phần mảng đã sắp xếp thứ tự Với cáchcải tiến này thì có thể duyệt trên cả 2 phía( trái, phải) của mảng, sau mỗi lầnduyệt có thể có nhiều phần tử được bổ xung vào mảng đã sắp xếp thứ tự Ví dụ
Trang 8có mảng số nguyên 44 55 12 64 06 94 67 Quá trình thực hiện giải thuật nhưsau
L:=2 phần tử a[i] bên trái có thứ tự (i < 1)
R:= n Phần tử a[r] a[n] bên phải đã có thứ tự
- Phân tích đánh giá giải thuật: Nếu sử dụng giải thuật rung thì:
+ Cmin = n
+ Cmax = n(n-1)/2+ Cavg = (n2 – nln – (b +ln2 – 1)n)/4 với b là hằng số Euler
2.3.1.2.4 Sắp xếp bằng đếm phân phối ( Distribution Cuonting)
Trong trường hợp khóa của các phần tử a[1], a[2], ,a[n] là các số nguyênnằm trong khoảng từ 0 tơi k, ta có thuật toán đơn giản và hiệu quả như sau:
Xây dựng dãy c[0], c[1] , , c[k], trong đó c[v] là số lần xuất hiện khóa Vtrong dãy
For v:= 0 to k do c[v]:=0; { Khởi tạo dãy c}
For i:=1 to n do c[a[i]]:= c[a[i]] +1;
Như vậy, sau khi sắp xếp:
- Các phần tử có khóa bằng 0 đứng trong đoạn từ vị trí 1 tới vị trí c[0]
- Các phần tử có khóa bằng 1 đứng trong đoạn từ vị trí c[0]+1 tới vị trí c[0] +c[1]
- Các phần tử có khóa bằng 2 đứng trong đoạn từ vị trí c[0] +c[1] + 1 tới vị tríc[0] + c[1] + c[2]
Trang 9Phần tử có khóa bằng 5 nằm ở vị trí 8.
Dãy khóa sau khi sắp xếp: 0, 0, 1, 2, 2, 2, 3, 5
Độ phức tạp của thuật toán là O(max(N,K))
Ví dụ 1: Cho một dãy X gồm N số nguyên trong phạm vi từ -10000 đến 10000
(1<= N<=100000) hãy sắp xếp dãy số này theo thứ tự giảm dần
Dữ liệu vào cho trong tệp File văn bản Sort.inp trong đó dòng đầu chứa số N Dòng thứ i trong N dòng tiếp theo chứa số thứ tự i trong dãy X
Kết quả ghi ra File văn bản với tên Sort.out trong đó lần lượt ghi ra các phần tửcủa dãy X đã được sắp xếp mỗi số trên một dòng
Ví dụ:
Sort.inp Sort.out4
3425
54 32
Lời giải:
Phương pháp sắp xếp mà chúng ta dùng là sắp xếp đếm ( Cuonting sort )
Phương pháp này tận dụng việc giới hạn của các số cần sắp xếp có thể lưu đủ trong bộ nhớ, trong bài toán này phạm vi các số là -10000 10000 ta sẽ dùng mảng dem[-10000 10000] trong đó dem[x] lưu số lần xuất hiện của số X trongdãy số
Bài toán này được ra với yêu cầu làm trên trình biên dịch Borland Pascal Với trình biên dịch cũ này, quản lý bộ nhớ là một điều quan trọng do dung lượng bộ nhớ bị hạn chế Tôi sẽ trình bày lời giải bài toán này trên cơ sở bộ nhớ hạn chế
đó
Do mỗi số có thể xuất hiện đến N<= 100000 nên mảng dem phải mang kiểu dữ liệu Longint( số nguyên 32 bit) trong Pascal Trong Borland Pascal, khi khai báo mảng 20000 phần tử Longint sẽ báo bị lỗi là không đủ bộ nhớ Có một cách
để giải quyết điều này:
Khai báo mảng dem với kiểu dữ liệu Word( có giới hạn từ 0 65535 ) như sau:Var dem:array[-10000 10000] of word;
Ta nhận xét chỉ có nhiều nhất một phần tử của mảng dem có thể có giá trị lớn hơn hoặc bằng 60000, vì tổng số lượng số nhiều nhất là 100000 Do đó ta quản
lý thêm một biến lưu phần tử đặc biệt có giá trị đếm vượt 60000 này ( nếu có)
Ta đặt tên biến này là V Đoạn lệnh dưới đây đọc vào các số và quản lý dữ liệu.For i:=1 to n do
Readln(X); { đọc vào một số X }
Inc(dem[x]); { tăng biến đếm số lần xuất hiện của số x }
If ( dem[x] = 60000) then { nếu đã có 60000 số x xuất hiện }
Begin
V:=x; { Lưu lại số x duy nhất này }
dem[x]:=0; { Gán lại biến đếm bằng 0 để tránh tràn số}
end;
Trang 10Đoạn lệnh dưới đây in ra các số đã sắp xếp theo thứ tự giảm dần:
For i:= 10000 downto -10000 { Duyệt qua các phạm vi của các số:
[-10000 10000] }
Begin
For j:=1 to dem[i] do writeln(i); { in ra số i với số lần là dem[i] }
If ( v=i) then for j:=1 to 60000 do { nếu i là số đặc biệt thì ta cần in thêm
60000 lần xuất hiện nữa }
N,i,v:longint;
BEGINAssign(input, finp); Reset(input);
Assign( output, fout); Rewrite( output);
Fillchar(dem,sizeof(dem),0);
readln(n);
V:=0;
For i:=1 to n doBegin
Readln(x);
Inc(dem[x]);
If (dem[x] = 60000) then
BeginV:=x;
If (v=i) then for j:= 1 to 60000 do writeln(i);
Trang 11Thuật toán tìm kiếm nhị phân có thể tìm phần tử có giá trị bằng X trên mảng
đã được sắp xếp một cách hiệu quả trong thời gian O(logn)
Thuật toán như sau
Giả sử cần tìm trong đoạn a[L], a[l+1],…,a[H] với giá trị khóa là X, trước hết ta xét giá trị của phần tử nằm giữa dãy có chỉ số là mid = (L+H) div 2
+ Nếu a[mid] =X thì việc tìm kiếm thành công( kết thúc quá trình tìm
kiếm)
+ Nếu a[mid]<X thì có nghĩa là đoạn từ a[L] tới a[mid] chỉ chứa các
giá trị < X, ta tiến hành tìm kiếm tiếp với đoạn từ a[mid +1] đến a[H] + Nếu a[mid]> X thì có nghĩa là đoạn từ a[mid] tới a[H] chỉ chứa các phần tử
có giá trị > X, ta tiến hành tìm kiếm tiếp với đoạn từ a[L] đến a[mid – 1]
Quá trình tìm kiếm sẽ thất bại nếu đến một bước nào đó, đoạn tìm kiếm là rỗng (tức là L > H)
if a[mid] = X then exit(mid );
If a[mid] < X then L := mod +1 else H:= mid -1;
End;
Exit(0);
End;
Ví dụ 3 Thống kê.
Cho dãy số a1, a2,…,an Hãy đếm số lượng giá trị khác nhau có trong dãy và đưa
ra số lần lặp của giá trị xuất hiện nhiều nhất
Ví dụ, dãy gồm 8 số: 6, 7, 1, 7, 4, 6, 6, 8 thì dãy có 5 giá trị khác nhau và số lần lặp của giá trị xuất hiện nhiều nhất trong dãy là 3
Giải
Các công việc trên sẽ được thực hiện đơn giản nếu mảng đã được sắp xếp, khi
đó các phần tử có giá trị bằng nhau sẽ đứng cạnh nhau ( liên tiếp nhau)
{ Xây dựng hàm cv trả về số giá trị khác nhau trong mảng a có n phần tử đã sắp xếp}
Function cv( a: tarray; n:longint):longint;
Var i, cuont:longint;
BeginCount:=1;
For i:= 2 to n do
If a[i-1]< > a[i] then inc(count);
Cv:=count;
Trang 12for i:=2 to n do begin
if a[i] < > a[i-1] then cuont:=1 else inc(cuont);
if count> r then r:= count;
end;
hf := r;
end;
2.3.1.2.5 Giải thuật sắp xếp nhanh
a Giải thuật Shell.
- Nguyên lý giải thuật Từ mảng ban đầu ta chia thành h(1) nhóm và thực hiệnh(1) – sort Sau đó ta lại chia làm h(2) nhóm và thực hiện h(2) – sort Cứ tiếp tụcnhư vậy cho tới khi ta chia h(t)=1 nhóm và thực hiện h(t) – sort
Từ nguyên lý này ta suy ra giải thuật chèn trực tiếp ( Straightinsertion) chỉ
là một trường hợp riêng của giải thuật Shell với h:=1 Ví dụ
42 44 94 12 55 67 06 40
42 44 06 12 55 67 94 40 4-sort
06 12 42 40 55 44 94 67 2-sort
06 12 40 42 44 55 67 94 1-sort
- Phân tích đánh giá giải thuật: Nếu sử dụng giải thuật Shell thì:
Với các bước chọn hợp lý, Knuth giới thiệu 2 cách chọn h (luôn luôn h(t) =1) h(i) = 2h(i+1) +1 và t = ruond(log2n)-1 Với cách chọn này ta có:
Giải thuật này tốt hơn các giải thuật trên [2]
b Giải thuật Heapsort
- Định nghĩa Heap: Một mảng số a(1) a(n) được gọi là một heap nếu thỏa mãnđiều kiện sau: Với mọi j, round(j/2) ϵ (l,r)
A(round(j/2).key ≤ a[j].key
- Tính chất của Heap:
Cho mảng a(1) a(n) luôn luôn tồn tại một Heap a(round(n/2)+ a(n)
Trang 13Nếu tồn tại một Heap a(1) a(n) thì luôn luôn có a(1).key bé nhất Ta có thể diễn
tả Heap dưới dạng một cây với nút gốc là nút bé nhất
- Nội dung của giải thuật:
+ Lấy a(1) ra khỏi Heap
+ Đem (a(2) a(n) so sánh để chọn nút gốc và cứ làm tiếp tục cho đến khi được một mảng có thứ tự
Giải thuật cơ bản của Heapsort là shift(l,r), mở rộng heap l+1 r thành heap l rPhân tích và đánh giá giải thuật: Nếu sử dụng giải thuật heapsort thì:
Cmax = 7n + 2nlog2n
Mmax = 17n/2+ nlog2n
Cavg = nlog2n-1.87nM= nlog2n - 0.9n
So với các giải thuật trên thì giải thuật này là lý tưởng vì trong mọi trường hợp
nó tỷ lệ với nlog2n [2]
c Giải thuật ( Quick Sort )
- Nguyên lý giải thuật: Sắp xếp 1 dãy được coi là sắp xếp một đoạn từ chỉ số 1đến chỉ số n Để sắp xếp một đoạn trong dãy, nếu đoạn chỉ có một phần tử thìdãy đã được sắp xếp, ngược lại ta chọn một phần tử x trong đoạn đó làm “chốt”,mọi phần tử có khóa nhỏ hơn khóa của “chốt” được xếp vào vị trí đứng trước
“chốt”, mọi phần tử có khóa lớn hơn “chốt” được xếp vào vị trí đứng sau chốt.Sau phép hoán chuyển như vậy thì đoạn đang xét được chia làm hai đoạn màmọi phần tử trong phần đầu của đoạn đều có khóa nhỏ hơn hoặc bằng (<=) khóacủa “chốt” và mọi phần tử trong phần sau của đoạn đều có khóa lớn hơn hoặcbằng(>=) khóa của “chốt” Tiếp tục sắp xếp kiểu như vậy với hai đoạn con, ta sẽđược đoạn đã cho được sắp xếp theo chiều tằng dần của khóa
- Phân tích và đánh giá giải thuật: Nếu sử dụng giải thuật Quick sort có cácthông số
2.3.2 Mô tả các giải thuật thông dụng
Như vậy ở mục 2.3.1 tôi đã mô tả tóm tắt nguyên lý và phân tích đánh giácác giải thuật sắp xếp Bạn đọc có thể sẽ cảm thấy đôi chỗ khó hiểu nhất là phầnđánh giá giải thuật, bạn có thể bỏ qua mục này, Phần sau đây tôi sẽ mô tả chi tiết
và minh họa chương trình cụ thể cho những gải thuật thông dụng
Chúng ta chia các giải thuật đã trình bày thành 2 loại:
- Loại giải thuật đơn giản hay còn gọi là giải thuật cổ điển như các giải thuật
chèn, chọn và đổi chỗ, với loại này, tôi nghiên cứu 2 giải thuật chọn trực tiếp vànổi bọt
- Loại giải thuật phức tạp tôi nghiên cứu về giải thuật Quicksort.
Trang 14Muốn sắp xếp các phần tử của mảng theo một thứ tự nào đó, chúng ta cần có 2thao tác cơ bản đó là
+ So sánh 2 phần tử với nhau
+ Hoán vị (thay đổi vị trí trong mảng)
Vậy tôi xây dựng 2 thao tác trên để sử dụng cho việc mô tác cho các giải thuậtsắp xếp dưới đây
- Tạo hàm so sánh: Đối với các kiểu dữ liệu chuẩn, để so sánh 2 dữ liệu cùngkiểu, Pascal ta sử dụng các toán tử so sánh (toán tử quan hệ) Nhưng với cáckiểu dữ liệu có cấu trức như kiểu mảng mà ta đang xét không thể sử dụng cáctoán tử quan hệ để so sánh 2 phần tử mảng với nhau được [2]
Vì vậy, để định nghĩa dữ liệu X bé hơn dữ liệu Y, nếu với điều kiện nào đócủa X bé hơn điều kiện của Y thì hàm so sánh behon cho kết quả đúng(true) vàngược lại cho kết quả sai(false)
Funtion behon(x,y:<kiểu>):boolear;
Begin
Behon:= < Biểu thức so sánh trên 2 dữ liệu>;End;
- Tạo thủ tục hoán vi 2 phần tử: Giả sử có 2 phần tử a[i] > a[i+1] nào đó, bây giờ
ta cần thay đổi vị trí để cho phần tử a[i+1] chuyển sang vị trí của phần tử a[i] vàphần tử a[i] lại chuyển sang vị trí của a[i+1] ta thực hiện như sau:
Sử dụng 1 biến tam để gán giá trị của phần tử a[i] cho biến này:
+ tam:= a[i];
+ Gán giá trị của phần tử a[i+1] cho a[i]: a[i]:= a[i+1];
+ Gán giá trị của tam cho phần tử a[i+1]: a[i+1]:= tam;
Thủ tục hoanvi như sau:
Procedure hoanvi( Var x,y:<kiểu>) ;
2.3.2.1 Mô tả cho giải thuật chọn trực tiếp
Như phần trình bầy về khái niệm, giải thuật chọn bắt đầu so sánh từ phần tửđầu tiên với phần tử còn lại Nếu thỏa nãm điều kiện so sánh( tăng dần hoặcgiảm dần) thì hoán đổi 2 phần tử với nhau, tiếp tục so sánh phần tử kế tiếp vớicác phần tử còn lại Thực hiện tiếp tục như vậy cho đến phần tử cuối cùng Muốn thực hiện trình tự như trên, chúng ta phải sử dụng 2 vòng lặp For+ Vòng lặp thứ nhất: Lần lượt chọn phần tử thứ i với i từ 1 đến n-1 để so sánh
và hoán vị với phần tử thứ j
+ Vòng lặp thứ hai: lần lượt chọn các phần tử thứ j với j từ i đến n
Giả sử chúng ta sắp xếp theo thứ tự tăng dần thì phải thực hiện hoán vị khi phần
tử thứ I > j Ngược lại, nếu sắp xếp giảm dần thì phải hoán vị khi j>i
Trang 15Ví dụ: Nếu muốn sắp xếp 1 mảng A có n phần tử thì thủ tục viết cho giải thuật
chọn trực tiếp như sau
Procedure Chon(Var a:<kiểu>; n :byte);
Tóm lại giải thuật chọn trực tiếp có ưu điểm là giải thuật đơn giản, dễ hiểukhi nghiên cứu và giảng dạy nhưng trong thực tế ta chỉ sử dụng khi n nhỏ vì sốlần sắp xếp khá nhiều( tương đương n2)[2]
Ví dụ: Chương trình sử dụng giải thuật chọn để sắp xếp từ nhỏ đến lớn các phần
min, vitri, i, j:integer;
Begin
Writeln(‘ sap xep mang bang giai thuat chon’);
For i:=1 to spt do
BeginWrite(‘ phan tu a[‘,i,’] =’); readln (a[i]);
End;
For i:=1 to spt do
Begin min:=a[spt];
Trang 16For i:=1 to spt doWriteln(a[i]:6);
writeln;
Readln;
End
2.3.2.2 Mô tả cho giải thuật nổi bọt
Giải thuật nổi bọt cũng duyệt mảng như giải thuật chọn nhưng so sánh vàhoán vị theo từng cặp phần tử i và i+1
Lần duyệt đầu tiên bắt đầu từ i=1 đến i= n-1, sau lần duyệt này, các phần tử
có giá trị nhỏ sẽ chuyển lên vị trí đầu, các phần tử có giá trị lớn sẽ chuyển xuốnggần vị trí cuối và phần tử thứ n chứa giá trị lớn
Lần duyệt thứ 2 cũng bắt đầu từ i=1 đến n-1, so sánh và hoán vị 2 cặp phần
Chu trình của giải thuật nổi bọt như sau:
* Vòng lặp for thứ nhất cho j từ n giảm dần đến 2 * Vòng lặp for thứ 2 cho i=1 đến j-1
* So sánh, nếu phần tử thứ i+1 bé hơn phần tử thứ i thì * Hoán vị
Ý tưởng này được thể hiện trong thủ tục sắp xếp nổi bọt sau đây:
Procedure Noibot(Var a:<kiểu>; n:byte);
Var
i.j:byte;
BeginFor j:=n downto 2 do
For i:=1 to j-1 do
If behon(a[i+1],a[i]) then hoanvi(a[i],a[i+1]);End;
Số lần so sánh của giải thuật này gồm:
- Lần duyệt đầu tiên, số lần so sánh là n-1
Var
Trang 17A:array[1 spt] of integer;
tam, i , j: integer;
BeginWriteln(‘ sap xep mang bang giai thuat noi bot’); For i:=1 to spt do
BeginWrite(‘ phan tu’,a[‘,i,’] =’); readln (a[i]);
End;
For i:=1 to spt -1 do
For j:=spt downto i+1 do
If a[j]< a[j-1] then
writeln;
Readln;
End
2.3.2.3 Mô tả cho giải thuật sắp xếp nhanh quicksort.
Giải thuật Quicksort được sử dụng trong trường hợp mảng có số phần tử lớn
và phức tạp, Số lần sắp xếp sắp xếp trung bình của giải thuật này là nlog(n), lớnnhất là n2 lần
Nguyên lý sắp xếp của giải thuật này gồm các bước như sau:
a Chia mảng thành 2 phần ( trái, phải) lấy một giá trị x ở giữa để làm chuẩn so sánh
b Tìm một phần tử A ở phần bên phải có giá trị lớn hơn x
c Tìm một phần tử B ở phần bên trái có giá trị nhỏ hơn x
d Hoán vị 2 phần tử A và B
e Tiếp tục thực hiện như thế cho đến khi đạt được một mảng mà phần bên trái là các phần tử có giá trị nhỏ hơn x, phần bên phải là các phần tử có các giá trị lớn hơn x
f Trong mỗi phần lại chia thành 2 phần nhỏ và thực hiện việc sắp xếp như trên cho các phần tử nhỏ này (bước b,c,d,e)
g Sau khi thực hiện bước f, mảng chia thành 4 phần Tiếp tực thực hiện bước (f,b,c,d,e) để chia mảng thành 8 phần vv…cho đến khi không thể chia được nữa việc sắp xếp mảng cũng hoàn tất
- Dưới đây tôi mô tả cú pháp đệ quy cho một đoạn của mảng từ phần tử thứL( bên trái) đến phần tử thứ R ( bên phải)
+ Lấy giá trị của phần tử ở giữa mảng [(L+R) div 2] gán cho biến x để làmchuẩn so sánh
Trang 18+ Sử dụng vòng lặp for với biến i có trị ban đầu là L ( thứ tự của các phần tử ởphần bên trái).
+ Sử dụng vòng lặp For với biến j có giá trị ban đầu là R( Thứ tự của các phần
tử ở phần bên phải)
+ Sử dụng vòng lặp Repeat cho đến khi i>j
Chừng nào a[i]<x thì tăng i
Chừng nào x<a[i] thì giảm j
Sử dụng điều kiện if , nếu i< = j thì :
Hoán vị 2 phần tử a[i] và a[j]
Tăng i
Giảm jCho đến khi i>j Tới đây, chúng ta được 2 phần:L, j và i, R ( vì i>j) Phần L, j làcác phần tử có các giá trị nhỏ hơn các giá trị của các phần tử ở phần i, R Tiếptục thực hiện giải thuật trên với 2 phần bằng cú pháp đệ quy
+ Sắp xếp mảng từ phần tử thứ L đến phần tử thứ j
+ Sắp xếp mảng từ phần tử thứ i đến phần tử thứ R
+ Chấm dứt
Thủ tục minh họa cho giải thuật trên
Procedure Quicksort( Var a:<kiểu mảng>; N:<Kiểu>);
Procedure Sort (L, R: byte);
While behon(x,a[j]) doDec(j);
Until i>j;
If L<j then Sort (L,j);
If i<R then Sort (i,R);
Trang 19ConstMax = 1000;
Type Mang= array[1 max] of integer;
Var A: mang;
Procedure quicksort(Var a: mang; Lo, Hi: integer);
Procedure Sort (left, right:integer);
Trang 20While a[i]< x doInc(i);
While x < a[j] doDec(j);
If i<= j then Begin
If i< right thenSort (i, right);
Ví dụ cho dãy 5 phần tử: 5, 7, 1, 3, 4 và k = 3 thì giá trị nhỏ thứ k là 4
Giải: Sắp xếp dãy theo giá trị tăng dần, số đứng thứ k của dãy là giá trị nhỏ thứ
k Bài toán này nếu n<= 5000 có thể sử dụng theo thuật toán nổi bọt như sách giáo khoa lớp 10 đưa ra, nhưng nếu n >= 5000 thì nên sử dụng thuật toán sắp xếp nhanh
Ta có thể tìm được giá trị nhỏ thứ k hiệu quả hơn không cần sắp xếp lại cả dãy
số, cụ thể như sau
+ Trong thuật toán sắp xếp nổi bọt ta chỉ cần sắp xếp đến phần tử thứ k, khi đó phần tử thứ k chính là phần tử có khóa nhỏ thứ k
For i:=1 to k do // i chạy đến k
For j:=n downto i+1 do
If a[j-1]>a[j] thenBegin
Tmp:=a[j];
A[j]:=a[j-1];
Trang 21End;
+ Trong thuật toán QuickSort ta thấy rằng:
Nếu k<L<h thì đoạn từ L đến h không cần sắp xếp vì đoạn này không ảnhhướng đến vị trí thứ k
Nếu L<= h< k thì đoạn từ L đến h cũng không cần sắp xếp vì đoạn này không ảnh hưởng đến vị trí thứ k
Nếu L<=k<=h thì ta sẽ xử lý đoạn này
While a[i]<x do inc(i);
While a[j]> x do dec(j);
2.4 Hiệu quả của đề tài nghiên cứu
Sau khi áp dụng đề tài nghiên cứu: “ SỬ DỤNG GIẢI THUẬT SẮP XẾP GIÚP HỌC SINH GIẢI CÁC BÀI TOÁN TRONG LẬP TRÌNH THEO ĐỊNH HƯỚNG PHÁT TRIỂN NĂNG LỰC ” đã giúp tôi rất nhiều trong quá trìnhgiảng dạy trên lớp, đặc biệt trong việc bồi dưỡng học sinh giỏi môn Tinhọc, bằng cách phân tích giảng dạy như trên, các em học sinh dễ dàng nắmvững các giải thuật sắp xếp nâng cao, giúp học sinh áp dụng giải được
Trang 22nhiều bài toán hay và khó khi lập trình, sử lý được dữ liệu lớn với thời gianngắn nhất, đảm bảo kiểm tra được hết cho các text đề ra
Kết quả thu được vì hạn chế số lượng trang trong đề tài sáng kiến này, tôixin phân tích, trình bầy qua một số bài tập ví dụ tiêu biểu mà tôi đã hướng dẫngiúp học sinh thực hiện đạt hiệu quả trong quá trình bồi dưỡng học sinh giỏimôn Tin học trong phần phụ lục kèm theo
3 Kết luận và đề xuất
3.1 Kết luận.
Qua thực tế giảng dạy tại các lớp 10A, 10K, 10G, 11A, 11K, 11G trườngTHPT Ba Đình, sau khi áp dụng đề tài bản thân tôi đã có thêm nhiều kinhnghiệm và kỹ năng để giảng dạy và truyền đạt cho các em về kỹ năng sử dụngthuật toán sắp xếp khi giải các bài toán ở mức độ phổ thông, đặc biệt là sử dụngthật toán sắp xếp bằng đếm phân phối và sắp xếp nhanh để giải được nhiều bàitoán hay và khó, mang lại những bài học bổ ích và lý thú Được các đồng nghiệpủng hộ
Từ kết quả học tập của các em tôi nhận thấy việc kết hợp cùng một lúcnhiều phương pháp dạy học là một việc làm hết sức cần thiết, phù hợp với yêucầu thực tiễn
Với chủ đề này cá nhân tôi vẫn đang tiếp tục nghiên cứu, áp dụng sâu vàrộng cho các chuyên đề tiếp theo ở mức độ nâng cao hơn Mục đích để mang lạicho các em học sinh của tôi những tiết học bổ ích, khai thác tính sáng tạo, tạohứng thú và kích lệ tài năng cho các em yêu thích và say mê học môn lập trìnhTin Học nói riêng và môn Tin Học nói chung
3.2 Kiến nghị
Nhà trường cần có sự đầu tư nâng cấp thêm cho phòng máy thực hành củahọc sinh, bổ xung thêm tài liệu, tranh minh hoạ, mô hình dạy học lập trình trongnhà trường, để các em có thêm tài liệu tham khảo, giáo viên nghiên cứu bài dạy
Đề tài sáng kiến trên tôi đã áp dụng cho kết quả rất khả quan trong côngtác giảng dạy của mình, tuy nhiên sáng kiến này không thể tránh khỏi nhữngthiếu sót, hạn chế của cá nhân tôi Vậy tôi kính mong nhận được sự đóng gópcủa các quý đồng nghiệp, những người quan tâm nội dung này để sáng kiếnhoàn thiện, mở rộng hơn
Tôi xin chân thành cảm ơn sâu sắc!
Xác nhận của thủ trưởng đơn vị
Nga sơn, ngày 28 tháng 5 năm 2021 Tôi xin cam đoan đây là sáng kiến kinh nghiệm của mình viết, độc lập nghiên cứu, không sao chép nội dung của người khác.
Người thực hiện
Vũ Thị Huệ