Tải bản đầy đủ (.doc) (21 trang)

skkn một số phương pháp sắp xếp trong chương trình tin học phổ thông

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 (142.76 KB, 21 trang )

SỞ GIÁO DỤC VÀ ĐÀO TẠO THANH HOÁ

TRƯỜNG THPT HOẰNG HÓA 2

SÁNG KIẾN KINH NGHIỆM

TÊN ĐỀ TÀI
MỘT SỐ PHƯƠNG PHÁP SẮP XẾP TRONG CHƯƠNG
TRÌNH TIN HOC PHỔ THÔNG

Người thực hiện: TRƯƠNG THỊ QUÝ
Chức vụ: Giáo viên
Đơn vị công tác: Trường THPT HOẰNG HÓA2
SKKN thuộc môn: Tin học

THANH HOÁ NĂM 2016


Sáng kiến kinh nghiệm
MỤC LỤC
A. PHẦN MỞ ĐẦU………………………………………………… ………….2
I. LÝ DO CHỌN ĐỀ TÀI.......................................................................................2
II. MỤC ĐÍCH NGHIÊN CỨU..............................................................................2
III. ĐỐI TƯỢNG VÀ PHẠM VI NGHIÊN CỨU.................................................2
1.Đối tượng..................................................................................................2
2. Phạm vi.....................................................................................................3
IV. NHIỆM VỤ VÀ PHƯƠNG PHÁP NGHIÊN CỨU:........................................3
B. PHẦN NỘI DUNG...........................................................................................4

I. CƠ SỞ LÝ LUẬN............................................................................. 4
1. Đánh giá thực trạng..................................................................................4


II. TỔNG QUAN....................................................................................................4
II.1.THỜI GIAN THỰC HIỆN CHƯƠNG TRÌNH.....................................4
II.1.1 Ðơn vị đo thời gian thực hiện………………………………...4
II.1.2 Thời gian thực hiện trong trường hợp xấu nhất………………5
III. CÁC PHƯƠNG PHÁP SẮP XẾP ĐƠN GIẢN……………………………...6
III.1 Sắp xếp chọn (SelectionSort)……………………………………….6
III.2 Sắp xếp chèn (InsertionSort)………………………………………...7
III.3 Sắp xếp nổi bọt (Bubble Sort)……………………………………….8
III.4 Sắp xếp nhanh (QUICKSORT)………………………………………9
III.5 Sắp xếp bằng đếm phân phối (Distribution Counting)……………..13
IV. MỘT SỐ VÍ DỤ VỀ THUẬT TOÁN SẮP SẾP……………………………14
V. HIỆU QUẢ CỦA ĐỀ TÀI:…………………………………………………..18

PHẦN C: KẾT LUẬN……………………………………………… 19
I. KẾT LUẬN …………………………………………………………………...19
II. NHỮNG KIẾN NGHỊ LÀM TĂNG TÍNH KHẢ THI CỦA ĐỀ TÀI……….19
III. Tài liệu tham khảo: ………………………………………………………….20

GV: Trương Thị Quý – Trường THPT Hoằng Hóa 2

2


Sáng kiến kinh nghiệm

A. PHẦN MỞ ĐẦU
I. LÝ DO CHỌN ĐỀ TÀI:
Năm học 2015 -2016 là năm tôi được tổ chuyên môn phân công dạy Tin học
11 và đứng ôn đội tuyển học sinh giỏi môn Tin học. Đứng trước nhiệm vụ của năm
học này, tôi đã lên kế hoạch và mục tiêu dạy học cho mình nhằm đạt hiệu quả dạy

học được tôt nhất cũng như sẽ đạt được chỉ tiêu đăng kí. Và khi ôn thi học sinh giỏi
thì tôi và học sinh thấy có rất nhiều thuật toán sắp sếp vậy thì nên sử dụng thuật
toán nào đây và thuật toán nào là tối ưu và phù hợp nhất với bài toán của mình.
Trong quá trình giảng dạy, tôi nhận thấy việc lựa chọn các thuật toán về sắp
xếp ở học sinh còn lúng túng chưa để ý đến thời gian và bộ nhớ khi thực hiện
chương trình. Mặt khác việc giới thiệu các thuật toán sắp xếp trong sách giáo khoa
Tin học 11 còn hạn chế về việc thể hiện và nhấn mạnh các thuật toán về sắp xếp.
Từ thực tế đó tôi mạnh dạn chon đề tài “ Một số phương pháp sắp xếp
trong chương trình Tin học phổ thông”
II. MỤC ĐÍCH NGHIÊN CỨU:
Đề tài xây dựng các phương pháp sắp xếp thành một hệ thống để cho học
sinh biết cách nhận biết và lựa chọn phương pháp một cách tổng quát thông qua các
tiêu chí cơ bản. Từ đó áp dụng giải nhanh các bài tập ôn tập và vận dụng để giải các
bài toán trong kiểm tra đánh giá, ôn thi học sinh giỏi.
Nhằm nâng cao nghiệp vụ công tác của bản thân và nâng cao chất lượng của
học sinh, giúp học sinh có hứng thú hơn trong quá trình học tập và ôn thi học sinh
giỏi.
III. ĐỐI TƯỢNG VÀ PHẠM VI NGHIÊN CỨU:
1. Đối tượng
Đối tượng nghiên cứu là học sinh lớp 11 và các học sinh trong đội tuyển học
sinh giỏi.

GV: Trương Thị Quý – Trường THPT Hoằng Hóa 2

3


Sáng kiến kinh nghiệm
2. Phạm vi
Phạm vi nghiên cứu nội dung bài 4 – Bài toán và thuật toán, một số bài toán

sắp xếp, thuật toán sắp xếp trong chương trình Tin học 10 để nắm vững hơn kiến
thức cho các em học sinh lớp 11 trong kiểm tra đánh giá và ôn thi học sinh giỏi.
IV. NHIỆM VỤ VÀ PHƯƠNG PHÁP NGHIÊN CỨU:
Để tìm hiểu cách dạy học đạt kết quả cao trong việc giới thiệu một số
phương pháp sắp xếp, bản thân tôi vận dụng sáng tạo cơ sở lí luận với thực tiễn dạy
học. Các kiến thức và kinh nghiệm dạy học được tôi trực tiếp tiến hành giảng dạy
trên lớp, ôn luyện thi học sinh giỏi từ năm 2009 tới nay.
Sáng kiến kinh nghiệm đang trình bày của tôi dựa theo các luận cứ khoa học
hướng đối tượng, cụ thể: thuyết trình, quan sát, điều tra cơ bản, phân tích kết quả
thực nghiệm sư phạm,v.v… phù hợp với bài học và môn học thuộc lĩnh vực cấu
trúc dữ liệu.

GV: Trương Thị Quý – Trường THPT Hoằng Hóa 2

4


Sáng kiến kinh nghiệm

B. PHẦN NỘI DUNG
I. CƠ SỞ LÝ LUẬN
1. Đánh giá thực trạng :
- Phần lớn học sinh đã nhận thấy vai trò của các thuật toán sắp xếp. Nhưng các
thuật toán mà các em biết chỉ hạn hẹp trong chương trình sách giáo khoa Tin học
11. Do đó để giải quyết hầu hết các bài toán đơn giản liên quan đến thuật toán sắp
xếp là rất khó khăn.
- Mặt khác nếu các em học sinh có linh hoạt sử dụng các phương pháp sắp xếp
trong chương trình phổ thông được thì chỉ đảm bảo được về mặt kết quả, còn về
đảm bảo thời gian chạy chương trình sao cho cứ mỗi test là 1 giây thì đa số học
sinh chưa giải quyết được.

- Do vậy nên đề tài đưa ra các thuật toán sắp xếp để học sinh nắm được và sử dụng
linh hoạt đồng thời cho học sinh thấy được thời gian chạy của từng chương trình
mà áp dụng với các bài toán có số liệu lớn, nhỏ khác nhau.
II. TỔNG QUAN
II.1.THỜI GIAN THỰC HIỆN CHƯƠNG TRÌNH
Thời gian thực hiện một chương trình là một hàm của kích thước dữ liệu vào,
ký hiệu T(n) trong đó n là kích thước (độ lớn) của dữ liệu vào.
Ví dụ 1-1: Chương trình tính tổng của n số có thời gian thực hiện là T(n) = cn
trong đó c là một hằng số.
Thời gian thực hiện chương trình là một hàm không âm, tức là
T(n) ≥ 0, ∀ n ≥ 0.
II.1.1 Ðơn vị đo thời gian thực hiện.
Ðơn vị của T(n) không phải là đơn vị đo thời gian bình thường như giờ, phút
giây... mà thường được xác định bởi số các lệnh được thực hiện trong một máy tính
lý tưởng.
Ví dụ 1-2: Khi ta nói thời gian thực hiện của một chương trình là T(n) = Cn thì
có nghĩa là chương trình ấy cần Cn chỉ thị thực thi.
GV: Trương Thị Quý – Trường THPT Hoằng Hóa 2

5


Sáng kiến kinh nghiệm
II.1.2 Thời gian thực hiện trong trường hợp xấu nhất.
Nói chung thì thời gian thực hiện chương trình không chỉ phụ thuộc vào kích
thước mà còn phụ thuộc vào tính chất của dữ liệu vào. Nghĩa là dữ liệu vào có cùng
kích thước nhưng thời gian thực hiện chương trình có thể khác nhau. Chẳng hạn
chương trình sắp xếp dãy số nguyên tăng dần, khi ta cho vào dãy có thứ tự thì thời
gian thực hiện khác với khi ta cho vào dãy chưa có thứ tự, hoặc khi ta cho vào một
dãy đã có thứ tự tăng thì thời gian thực hiện cũng khác so với khi ta cho vào một

dãy đã có thứ tự giảm.
Vì vậy thường ta coi T(n) là thời gian thực hiện chương trình trong trường hợp
xấu nhất trên dữ liệu vào có kích thước n, tức là: T(n) là thời gian lớn nhất để thực
hiện chương trình đối với mọi dữ liệu vào có cùng kích thước n.
II.2. CÁCH SẮP XẾP DỮ LIỆU VÀ NGÔN NGỮ SỬ DỤNG
Danh sách các đối tượng cần được sắp xếp là một mảng lưu trữ các kiểu dữ
liệu có quan hệ thứ tự (như kiểu số nguyên, số thực, …)
Mục đích của việc sắp xếp là tổ chức lại các phần tử trong mảng sao cho
chúng được sắp thứ tự tương ứng với quy luật sắp xếp.
Ðể trình bày các ví dụ minh họa chúng ta sẽ dùng PASCAL làm ngôn ngữ thể
hiện và sử dụng khai báo sau:
CONST N = 10;
Var a: array[1..N]of integer;
Procedure hd(var x,y:integer);
Var

tg:integer;

Begin
tg:=x;
x:=y;
y:=tg;
End;

Cần thấy rằng thủ tục hd lấy O(1) thời gian vì chỉ thực hiện 3 lệnh gán nối tiếp
GV: Trương Thị Quý – Trường THPT Hoằng Hóa 2

6



Sáng kiến kinh nghiệm
nhau.
III. CÁC PHƯƠNG PHÁP SẮP XẾP ĐƠN GIẢN.
III.1 Sắp xếp chọn (SelectionSort)
a) Phương pháp:
Ðây là phương pháp sắp xếp đơn giản nhất được tiến hành như sau:
• Ðầu tiên chọn phần tử có giá trị nhỏ nhất trong n phần tử từ a[1] đến a[n] và
hoán vị nó với phần tử a[1].
• Chọn phần tử có giá trị nhỏ nhất trong n-1phần tử từ a[2] đến a[n] và hoán vị
nó với a[2].
• Tổng quát ở bước thứ i, chọn phần tử có giá trị nhỏ nhất trong n-i+1 phần
tử từ a[i] đến a[n] và hoán vị nó với a[i].
• Sau n-1 bước này thì mảng đã được sắp xếp.
Phương pháp này được gọi là phương pháp chọn bởi vì nó lặp lại quá trình
chọn phần tử nhỏ nhất trong số các phần tử chưa được sắp.

b) Chương trình:
PROCEDURE SelectionSort;
VAR
T,i,j,y: integer;
BEGIN
{1} FOR i := 1 TO n-1 DO BEGIN
{2}
T := a[i];
{3}
FOR j := i+1 TO n DO
{4}
IF a[j] < T THEN
BEGIN
{5}

T := a[j];
{6}
y := j;
END;
{7} hd(a[i],a[y]);
END;
END;

c) Đánh giá:
Trước hết ta có thủ tục hd một hằng thời gian như đã nói ở mục trên.
Các lệnh {2} lấy O(1) thời gian. Vòng lặp for {3} – {6} thực hiện n-i lần, vì
GV: Trương Thị Quý – Trường THPT Hoằng Hóa 2

7


Sáng kiến kinh nghiệm
j chạy từ i+1 đến n, mỗi lần lấy O(1), nên lấy O(n-i) thời gian. Do đó thời gian tổng
cộng là:
n(n − 1)
T(n) = 2

tức là O(n2).

III.2 Sắp xếp chèn (InsertionSort)
a) Phương pháp:
Trước hết ta xem phần tử a[1] là một dãy đã có thứ tự.
• Bước 1, xen phần tử a[2] vào danh sách đã có thứ tự a[1] sao cho a[1], a[2] là
một danh sách có thứ tự.
• Bước 2, xen phần tử a[3] vào danh sách đã có thứ tự a[1], a[2] sao cho

a[1], a[2], a[3] là một danh sách có thứ tự.
•Tổng quát, bước i, xen phần tử a[i+1] vào danh sách đã có thứ tự
a[1],a[2],..a[i] sao cho a[1], a[2],.. a[i+1] là một danh sách có thứ tự.
• Phần tử đang xét a[j] sẽ được xen vào vị trí thích hợp trong danh sách các
phần tử đã được sắp trước đó a[1],a[2],..a[j-1] bằng cách so sánh giá trị của a[j] với
giá trị của a[j-1] đứng ngay trước nó. Nếu giá trị của a[j] nhỏ hơn giá trị của a[j-1]
thì hoán đổi a[j-1] và a[j] cho nhau và tiếp tục so sánh giá trị của a[j-1] (lúc này a[j1] chứa nội dung của a[j]) với giá trị của a[j-2] đứng ngay trước nó...
b) Chương trình:
PROCEDURE InsertionSort;
VAR
i,j: integer;
BEGIN
{1} FOR i := 2 TO n DO BEGIN
{2}
J := i;
{3}
WHILE (j>1) AND (a[j] < a[j-1])
DO BEGIN
{4}
hd(a[j], a[j-1]);
{5}
j := j-1;
END;
END;
END;

GV: Trương Thị Quý – Trường THPT Hoằng Hóa 2

8



Sáng kiến kinh nghiệm
c) Đánh giá:
Ta thấy các lệnh {4} và {5} đều lấy O(1). Vòng lặp {3} chạy nhiều nhất i-1
lần, mỗi lần tốn O(1) nên {3} lấy i-1 thời gian. Lệnh {2} và {3} là hai lệnh nối tiếp
nhau, lệnh {2} lấy O(1) nên cả hai lệnh này lấy i-1. Vòng lặp {1} có i chạy từ 2 đến
n nên nếu gọi T(n) là thời gian để sắp n phần tử thì ta có:
n(n − 1)
T(n) = 2

tức là O(n2).

III.3 Sắp xếp nổi bọt (Bubble Sort)
a) Phương pháp:
Chúng ta tưởng tượng rằng các phần tử được lưu trong một mảng dọc, qua quá
trình sắp, phần tử nào có giá trị “nhẹ” sẽ được nổi lên trên. Chúng ta duyệt toàn
mảng, từ dưới lên trên. Nếu hai phần tử ở cạnh nhau mà không đúng thứ tự tức là
nếu phần tử “nhẹ hơn” lại nằm dưới thì phải cho nó “nổi lên” bằng cách đổi chỗ hai
phần tử này cho nhau. Cụ thể là:
• Bước 1: Xét các phần tử từ a[n] đến a[2], với mỗi phần tử a[j], so sánh giá trị
của nó với giá trị của phần tử a[j-1] đứng ngay trước nó. Nếu giá trị của a[j] nhỏ
hơn giá trị của a[j-1] thì hoán đổi a[j] và a[j-1] cho nhau.
• Bước 2: Xét các phần tử từ a[n] đến a[3], và làm tương tự như trên.
• Sau n-1 bước thì kết thúc.

b) Chương trình:
PROCEDURE BubbleSort;
VAR
i,j: integer;
BEGIN

{1} FOR i := 1 to n-1 DO
{2}
{3}
{4}

FOR j := n DOWNTO i+1 DO
IF a[j] < a[j-1] THEN
hd(a[j],a[j-1]);

GV: Trương Thị Quý – Trường THPT Hoằng Hóa 2

9


Sáng kiến kinh nghiệm
END;

c) Đánh giá:
Dòng lệnh {3} lấy một hằng thời gian. Vòng lặp {2} thực hiện (n-i) bước, mỗi
bước lấy O(1) nên lấy O(n-i) thời gian. Như vậy đối với toàn bộ chương trình ta có:
n(n − 1)

T(n) = 2

tức là O(n2).

Một thuật toán nữa cũng có thời gian thực hiện O(n2) là:
for i:=1 to n-1 do
for j:=i+1 to n do
if a[i]>a[j] then hd(a[i],a[j])

end;

III.4 Sắp xếp nhanh (QUICKSORT).
a. Phương pháp:
Chúng ta vẫn xét mảng a các phần tử a[1]..a[n]. Giả sử v là 1 giá trị mà ta gọi
là chốt (pivot). Ta phân hoạch dãy a[1]..a[n] thành hai mảng con "bên trái" và "bên
phải". Mảng con "bên trái" bao gồm các phần tử có giá trị nhỏ hơn chốt, mảng con
"bên phải" bao gồm các phần tử có giá trị lớn hơn hoặc bằng chốt.
Sắp xếp mảng con “bên trái” và mảng con “bên phải” thì mảng đã cho sẽ được
sắp bởi vì tất cả các giá trị trong mảng con “bên trái“ đều nhỏ hơn các giá trị trong
mảngcon “bên phải”.
Việc sắp xếp các mảng con “bên trái” và “bên phải” cũng được tiến hành bằng
phương pháp nói trên.
Một mảng chỉ gồm một phần tử hoặc gồm nhiều phần tử có giá trị bằng nhau
thì đã có thứ tự.
Chọn giá trị lớn nhất trong hai phần tử có giá trị khác nhau đầu tiên kể từ trái
qua.
Nếu mảng chỉ gồm một phần tử hay gồm nhiều phần tử có giá trị bằng nhau thì
không có chốt.
GV: Trương Thị Quý – Trường THPT Hoằng Hóa 2

10


Sáng kiến kinh nghiệm
Ðể phân hoạch mảng ta dùng 2 "con nháy" L và R trong đó L từ bên trái và R
từ bên phải, ta cho L chạy sang phải cho tới khi gặp phần tử có giá trị ≥ chốt và cho
R chạy sang trái cho tới khi gặp phần tử có giá trị < chốt. Tại chỗ dừng của L và R
nếu L < R thì hoán vị a[L], a[R]. Lặp lại quá trình dịch sang phải, sang trái của 2
"con nháy" L và R cho đến khi L > R. Khi đó L sẽ là điểm phân hoạch, cụ thể là

a[L] là phần tử đầu tiên của mảng con “bên phải”.

b) Chương trình:
FUNCTION Findch(i,j:integer): integer;
VAR c,k : integer;
BEGIN
{1} k := i+1;
{2} c := a[i];
{3} WHILE (k <= j) AND (a[k]= c) DO k:= k+1;
{4} IF k > j THEN Fidch := 0
ELSE
{5}IF a[k] > c THEN Findch := k
ELSE Findch := i;
END;

Trong hàm Findch các lệnh {1}, {2}, {3} và {4} nối tiếp nhau, trong đó chỉ có
lệnh WHILE là tốn nhiều thời gian nhất do đó thời gian thực hiện của hàm Findch
phụ thuộc vào thời gian thực hiện của lệnh này. Trong trường hợp xấu nhất (không
tìm thấy chốt) thì k chạy từ i+1 đến j, tức là vòng lặp thực hiện j-i lần, mỗi lần O(1)
do đó tốn j-i thời gian. Đặc biệt khi i=1 và j=n, thì thời gian thực hiện là n-1 hay
T(n) = O(n).
Hàm Phanhoach nhận vào ba tham số i, j và chốt để thực hiện việc phân hoạch
mảng a[i]..a[j] theo chốt và trả về giá trị L là chỉ số đầu tiên của mảng “bên phải”.
Hai con nháy L, R sẽ được sử dụng để thực hiện việc phân hoạch như đã trình bày.
FUNCTION Phanhoach(i,j,c:integer):integer ;

GV: Trương Thị Quý – Trường THPT Hoằng Hóa 2

11



Sáng kiến kinh nghiệm
VAR L,R : integer;
BEGIN
{1} L := i; {Ðặt con nháy L ở cực trái}
{2} R := j; {Ðặt con nháy R ở cực phải}
{3} WHILE L <= r DO BEGIN
{L tiến sang phải}
{4}

WHILE a[L] < c DO L := L+1;

{R tiến sang trái}
{5}

WHILE a[R] >= c DO R := R-1;

{6}

IF L < R THEN hd(a[L],a[R]);

END;
{7} Phanhoach := L; {Trả về điểm phân hoạch}
END;

Trong hàm Phanhoach các lệnh {1}, {2}, {3} và {7} nối tiếp nhau, trong đó
thời gianthực hiện của lệnh {3} là lớn nhất, do đó thời gian thực hiện của lệnh {3}
sẽ là thời gian thực hiện của hàm Phanhoach. Các lệnh {4}, {5} và {6} là thân của
lệnh {3}, trong đó lệnh {6} lấy O(1) thời gian. Lệnh {4} và lệnh {5} thực hiện việc
di chuyển L sang phải và R sang trái, thực chất là duyệt các phần tử mảng, mỗi

phần tử một lần, mỗi lần tốn O(1) thời gian. Tổng cộng việc duyệt này tốn j-i thời
gian. Vòng lặp {3} thực chất là để xét xem khi nào thì duyệt xong, do đó thời gian
thực hiện của lệnh {3} chính là thời gian thực hiện của hai lệnh {4} và {5} và do
đó là j-i. Đặc biệt khi i=1 và j=n ta có T(n) = O(n).
Bây giờ chúng ta trình bày thủ tục cuối cùng có tên là QuickSort và chú ý rằng để
sắp xếp mảng A gồm n phần tử ta chỉ cần gọi QuickSort(1,n).
PROCEDURE
VAR
u,v,
BEGIN
v :=
IF v

Quicksort(i,j:integer);
k : integer;
Findch(i,j);
<> 0 THEN

GV: Trương Thị Quý – Trường THPT Hoằng Hóa 2

12


Sáng kiến kinh nghiệm
BEGIN
u := a[v];
k := Phanhoach(i,j,u);
QuickSort(i,k-1);
QuickSort(k,j);
END;

END;

Giả sử các giá trị của mảng khác nhau nên hàm Findch luôn tìm được chốt và
đệ quy chỉ dừng khi kích thước bài toán bằng 1.
Gọi T(n) là thời gian thức hiện việc QuickSort mảng có n phần tử.
Thời gian để tìm chốt và phân hoạch mảng như đã phân tích đều là O(n) = n.
Khi n = 1, thủ tục QuickSort chỉ làm một nhiệm vụ duy nhất là gọi hàm
Findch với kích thước bằng 1, hàm này tốn thời gian O(1) =1.
Trong trường hợp xấu nhất là ta luôn chọn phải phần tử có giá trị lớn nhất làm
chốt, lúc bấy giờ việc phân hoạch bị lệch tức là mảng bên phải chỉ gồm một phần
tử chốt, còn mảng bên trái gồm n-1 phần tử còn lại. Khi đó ta có thể thành lập
phương trình đệ quy như sau:
T(n)=

1

nêu n = 1

T(n - 1) + T(1) + n nêu n > 1

Giải phương trình này bằng phương pháp truy hồi T(n) =O(n2)
Có trường hợp thực thi cỡ O(nlogn) trong ttrường hợp trung bình
c) Kết luận:
Nếu chương trình ít gọi tới thủ tục sắp xếp và chỉ trên tập dữ liệu nhỏ, thì
việc sủ dụng một thuật toán phức tạp (tuy có hiệu quả) là không cần thiết, khi đó có
thể sử dụng thuật toán đơn giản có độ phức tạp O(N2), dễ cài đặt. Tuy nhiên vì độ
phức tạp là O(N2) nên thời gian thực hiện tăng lên 4 lần khi số lượng phần tử tăng
lên gấp đôi. Do đó, trong trường hợp sắp xếp với dữ liệu lớn thì nên sử dụng thuật
toán sắp xếp nhanh.
III.5 Sắp xếp bằng đếm phân phối (Distribution Counting)

a) Phương pháp:
Trong trường hợp khoá các phần tử a[1],a[2], … ,a[n] là các số nguyên trong
GV: Trương Thị Quý – Trường THPT Hoằng Hóa 2

13


Sáng kiến kinh nghiệm
nằ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[2],…,C[k] trong đó C[v] là số lần xuất hiện của khoá
V trong 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].key] := c[a[i].key] + 1;

Như vậy sau khi sắp sếp
Các phần tử có khoá bằng 0 đứng trong đoạn từ vị trí 1 đến vị trí C[0]
Các phần tử có khoá bằng 1 đứng trong đoạn từ vị trí C[0]+1 đến vị trí C[0] +C[1]
Các phần tử có khoá bằng 2 đứng trong đoạn từ vị trí C[0] +C[1] +1 đến vị trí
C[0]+ C[1] +C[2].
….
Các phần tử có khoá bằng V đứng trong đoạn từ vị trí C[0] + C[1]+…+C[V-1] + 1
đến vị trí C[0]+ C[1] +C[2] +….+ C[V-1] +C[V]
…..
Các phần tử có khoá bằng K đứng trong đoạn từ vị trí C[0]+C[1]+…+C[K-1]+1
đến vị trí C[0]+ C[1] +C[2] +….+ C[K1] +C[K]
b. Đánh giá:
Độ phức tạp của thuật toán là: T(n)= O(Max(N,K))
Với thuật toán này rất phù hợp với những dạng bài tập liên quan tới tìm tần suất
số lần xuất hiện của các phần tử trong mảng hoặc trong xâu……


GV: Trương Thị Quý – Trường THPT Hoằng Hóa 2

14


Sáng kiến kinh nghiệm
IV. MỘT SỐ VÍ DỤ VỀ THUẬT TOÁN SẮP SẾP
VD1: Cho dãy a1, a2, a3, ...,an, cá c đôi một khác nhau và số nguyên dương
k(1<=k<=n). Hãy đưa ra giá trị nhỏ thứ k trong dãy
Giải:
- Nếu n<= 5000 ta có thể sử dụng thuật toán sắp xếp nổi bọt có độ phức tạp O(n2).
- nếu n >=5000 ta nên sử dụng thuật toán QUICKSORT
Ta có thể tìm được giá trị nhỏ thứ k hiệu quả hơn cụ thể như sau:
Sử dụng thuật toán nổi bọt và chỉ sắp xếp đến phần tử thứ k
For i:=1 to k do
For j:=n downto i+1 do
If

a[j-1] >a[j] then
Begin
Tg:=a[j];
A[j]:=a[j-1];
A[j-1]:=tg;
End;
Sử dụng thuật toán sắp xếp nhanh:
Procedure

quicksort(l,h:longint);

Var I,j:longint; x,tg:longint;

Begin
If (l<=k) and( h>=k) then
Begin
i:=l;
j:=h;
x:=a[(h+l) div 2];
repeat
while a[i]GV: Trương Thị Quý – Trường THPT Hoằng Hóa 2

15


Sáng kiến kinh nghiệm
while a[j]>x do j:=j-1;
if

i<=j then

begin
tg:=a[i];
a[i]:=a[j];
a[j]:=tg;
i:= i+1;
j:=j- 1;
end;
until i>j;
if lif iend;

end;
Bài 2: Xét tập F(n) tất cả các số hửu tỷ thuộc trong đoạn [0, 1] với mẫu số không
vượt qua N (1 ≤ N ≤ 100)
Yêu cầu : Sắp xếp các phân số trong tập F(N) theo thứ tụe tăng dần, đưa ra phân số
thứ K.
Dữ liệu vào: Vào từ file PHANSO.INP chứa duy nhất số N.
Dữ liệu ra: Ghi ra file PHANSO.OUT chứa một dòng là dãy phân số đã được sắp
xếp tăng dần.
Ví dụ :
PHANSO.INP PHANSO.OUT
7
0/1; 1/7; 1/6; 1/5; 1/4; 2/7; 1/3; 2/5; 3/7; 1/2; 4/7; 3/5; 2/3; 5/7;
3/4; 4/5; 5/6; 6/7; 1/1
Giải :
- Khi nhìn vào bài toán ta thấy rằng đây ta có thể sử dụng thuật toán sắp xếp tương
tự thật toán sắp xếp nổi bọt và cùng có độ phức tạp la O(n 2). Vì do N nhỏ nên
chúng ta không nhất thiết phải sử dụng QUICKSORT.

GV: Trương Thị Quý – Trường THPT Hoằng Hóa 2

16


Sáng kiến kinh nghiệm
- Xét các phần tử của dãy ta thấy phần tử của dãy gồm phức hợp của 3 giá trị : Tử
số, mẫu số và thương nên ta sử dụng mảng một chiều kiểu bản ghi để lưu các giá trị
đó và sắp sếp chúng tăng dần.
- Các tử số của phần tử i sẽ nhận giá trị từ 0 đến N. Các mẫu số sẽ nhận giá trị từ
i+1 đến N.
- Dùng hàm UCLN để rút gọn phân số.

Code :
const fi='bai1.inp';
fo='bai2.out';
type phanso = record
x,y: longint;
end;
var
n: longint;
i,j: longint;
a: array[1..100,1..100] of boolean;
b: array[1..5000] of phanso;
procedure
nhapdl;
begin
assign(input, fi); reset(input);
assign(output, fo); rewrite(output);
readln(n);
end;
procedure
dongdl;
begin
close(input); close(output);
end;
function ucln(a,b: longint): longint;
begin
while (a<>0) and(b<>0) do
if a>b then a:= a mod b
else b:= b mod a;
exit(a+b);
end;

procedure
xuli;
var i,ii,j: longint;tg: phanso;
begin
fillchar(a, sizeof(a), false);
for i:= 1 to n-1 do
for j:= i+1 to n do a[i div ucln(i,j), j div ucln(i,j)]:=
true;
ii:=0;
for i:= 1 to n-1 do
for j:= i+1 to n do
if a[i,j] then
begin
inc(ii);

GV: Trương Thị Quý – Trường THPT Hoằng Hóa 2

17


Sáng kiến kinh nghiệm
b[ii].x:=i;
b[ii].y:=j;
end;
n:=ii;
for i:= 1 to n-1 do
for j:= i+1 to n do
if b[i].x/b[i].y >b[j].x/b[j].y then
begin
tg:= b[i];

b[i]:= b[j];
b[j]:= tg;
end;
end;
procedure
inkq;
begin
write('0/1');
for i:= 1 to n do write(b[i].x,'/',b[i].y);
write('1/1');
end;
BEGIN
nhapdl;
xuli;
inkq;
dongdl;
END.

Bài 3: Cho dãy gồm N (N ≤ 30000) số tự nhiên không vượt quá 109, tìm số tự
nhuên nhỏ nhất không xuất hiện trong dãy.
Dữ liệu vào file SN.INP có dạng
- Dòng đầu là số nguyên N
- Dòng thứ hai gồm N số
Kết quả ra file SN.OUT có dạng : số tự nhiên nhỏ nhất không xuất hiện trong dãy.
SN.INP
5
5 0
3

SN.OUT

2
1

4

Giải :
- Số nhỏ nhất không xuất hiện trong dãy sẽ nằm trong đoạn [0,n]. Do đó, ta sử dụng
phương pháp sắp xếp bằng đếm phân phối : sử dụng mảng c : array[0..30000] of
longint ; với C[X] là số lần xuất hiện của X trong dãy, nếu C[X]=0 thì X là không
xuất hiện trong dãy.
Code :
var

c:array[0..30000] of longint;
n,i,x:longint;
f1,f2:text;

GV: Trương Thị Quý – Trường THPT Hoằng Hóa 2

18


Sáng kiến kinh nghiệm
begin
fillchar(c,sizeof(c),0);
assign(f1,'SN.INP');assign(f2,'SN.out');
reset(f1);Rewrite(f2);
readln(f1,n);
for i:=1 to n do
begin

read(f1,x);
if x<=n then inc(c[x]);
end;
for i:=0 to n do
if c[i]=0 then
begin
x:=i;
break;
end;
write(f2,x);
close(f1);close(f2);
end.
V. HIỆU QUẢ CỦA ĐỀ TÀI:
1.Từ thực tế giảng dạy trên lớp và qua quá trình bồi dưỡng học sinh giỏi tôi
rút ra một vài kinh nghiệm nhỏ trong việc giải bài toán có sử dụng thuật toán sắp
xếp. Phải cho học sinh nắm vững các phương pháp sắp xếp cơ bản và có thể vận
dụng vào các bài toán cụ thể nào đó sao cho ta có thể thu được kết quả đúng và với
thời gian cho phép.
2. Đối với giáo viên: Trong quá trình dạy về phương pháp sắp xếp nên nhấn
mạnh ưu điểm của từng phương pháp và thời gian thực hiện cho học sinh.
3. Đối với học sinh: Qua đây có thể phân biệt được rõ hơn về các phương pháp
sắp xếp để có thể sử dụng thiết kế thuật toán cho hợp lí.

PHẦN C: KẾT LUẬN
I. KẾT LUẬN :
GV: Trương Thị Quý – Trường THPT Hoằng Hóa 2

19



Sáng kiến kinh nghiệm
Sau khi việc thực hiện áp dụng phương pháp vào việc giảng dạy môn tin học
ở chương trình phổ thông tôi đã thu được nhiều thành công vượt trội hơn hẳn. Học
sinh dễ dàng nhận dạng và thể hiện các bài toán tin học sau khi hiểu và vận dụng
phương pháp thì chất lượng đã tăng lên rõ rệt. Điều này đã chứng minh tính đúng
đắn của phương pháp, chứng minh kết quả trong phương pháp dạy học trong
trường phổ thông đối với bộ môn Tin. So sánh tỉ lệ học sinh hiểu được thuật toán
bằng phương pháp này trên những đối tượng học sinh ta hoàn toàn tin tưởng vào
kết quả thu được về khả năng nhận dạng và thể hiện bài toán. Thực tế tôi đã theo
dõi trên các lớp đã dạy thì tỉ lệ năm bắt được các bài toán và thuật toán đã tăng lên
từ 25-30% so với khi chưa áp dụng.
II. NHỮNG KIẾN NGHỊ LÀM TĂNG TÍNH KHẢ THI CỦA ĐỀ TÀI.
a. Đối với trường.
- Có thể dành cho giáo viên có áp dụng phương pháp này nhằm làm tăng chất
lượng giảng dạy và kết quả học tập của học sinh. Không chỉ đối với giáo viên giảng
dạy môn Tin học mà có thể áp dụng phương pháp này cho những bộ môn khoa học
khác, đặc biệt là các bộ môn khoa học tự nhiên như Toán, Lý, Hoá, Sinh.
b. Đối với các Phòng GD-ĐT và Sở GD-ĐT.
- Có thể triển khai những phương pháp mới giúp cho giáo viên có thể vận
dụng kết hợp được nhiều phương pháp giảng dạy giúp làm tăng kết quả giảng dạy
cho giáo viên và kết quả học tập của học sinh, phát huy hết được tinh tư duy sáng
tạo trong học tập.
Trong quá trình thực hiện viết sáng kiến còn có nhiều hạn chế, không tránh
khỏi những thiếu sót, rất mong sự đóng góp ý kiến để SKKN được hoàn thiện hơn.

GV: Trương Thị Quý – Trường THPT Hoằng Hóa 2

20



Sáng kiến kinh nghiệm
III. Tài liệu tham khảo:
1. Sách giáo khoa Tin học 11.
2. Sách giáo khao chuyên Tin.
3. Giải thuật và lập trình – T.S Lê Minh Hoàng – ĐHSP Hà Nội.
4. Một số tài liệu từ Internet.
Xác nhận của Hiệu trưởng

Hoằng Hoá, ngày 01 tháng 04 năm 2016
Tôi xin cam đoạn đây là SKKN của mình viết,
không sao chép nội dung của người khác.
Người viết

Trương Thị Quý

GV: Trương Thị Quý – Trường THPT Hoằng Hóa 2

21



×