1. Trang chủ
  2. » Giáo Dục - Đào Tạo

Phân tích, vận dụng các thuật toán sắp xếp để giải quyết một số bài toán viết bằng NNLT c++

39 24 0

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 39
Dung lượng 238 KB

Các công cụ chuyển đổi và chỉnh sửa cho tài liệu này

Nội dung

SỞ GIÁO DỤC VÀ ĐÀO TẠO NGHỆ ANSÁNG KIẾN KINH NGHIỆM ĐỀ TÀIPHÂN TÍCH, VẬN DỤNG CÁC THUẬT TOÁN SẮP XẾP ĐỂ GIẢI QUYẾT MỘT SỐ BÀI TOÁN VIẾT BẰNG NNLT C++ SKKN thuộc lĩnh vực: Tin học Nghệ An

Trang 1

SỞ GIÁO DỤC VÀ ĐÀO TẠO NGHỆ AN

SÁNG KIẾN KINH NGHIỆM

ĐỀ TÀIPHÂN TÍCH, VẬN DỤNG CÁC THUẬT TOÁN SẮP XẾP ĐỂ GIẢI QUYẾT MỘT SỐ BÀI TOÁN VIẾT BẰNG NNLT C++

SKKN thuộc lĩnh vực: Tin học

Nghệ An năm 2021

Trang 2

1 MỞ ĐẦU

1.1 Lý do chọn đề tài

Chúng ta biết rằng để có kết quả cao trong kì thi tuyển chọn học sinh giỏimôn tin học nói chung thì phải có vốn kiến thức về thuật toán để giải được cácbài toán khó, hoặc những bài toán dữ liệu vào lớn, sau đó học sinh lựa chọnNNLT để lập trình dựa vào thuật toán đã tìm được và giải bài toán theo yêu cầu.Trong quá trình dạy bồi dưỡng học sinh giỏi tôi gặp rất nhiều bài toán có sửdụng giải thuật sắp xếp Đây là dạng bài tập không khó nhưng học sinh thườnghay chủ quan nên không chạy được hết các test lớn

Nguyên nhân cơ bản là học sinh không áp dụng phương pháp phù hợp chobài toán đó

Với mong muốn giúp học sinh giải quyết tốt hơn các bài tập sắp xếp dãy số,tôi đã dày công nghiên cứu các thuật toán sắp xếp và phân tích để áp dụng vàotừng dạng toán phù hợp

Mặt khác, theo chương trình mới của Bộ Giáo Dục khuyến khích giáo viêndạy NNLT mới thay Pascal nên tôi viết chương trình bằng NNLT C++ để làmtài liệu tham khảo mới cho giáo viên và học sinh

Từ những lý do trên tôi đã mạnh dạn trình bày sáng kiến kinh nghiệm:

“Phân tích, vận dụng các thuật toán sắp xếp để giải quyết một số bài toán viết bằng NNLT C++”.

1.2 Mục đích nghiên cứu

Mục đích chính của sáng kiến là nghiên cứu, phân tích và vận dụng cácthuật toán sắp xếp dành cho đối tượng HSG khối THPT Việc lĩnh hội được sángkiến sẽ giúp học sinh:

- Mô tả đúng khái niệm, bản chất và mục đích của việc sắp xếp

- Trình bày và thực hiện cài đặt một cách chính xác các thuật toán sắp xếp

- Đánh giá đúng về các thuật toán sắp xếp và tìm ra thuật toán sắp xếp phùhợp cho từng bài toán

- Giúp các em học giỏi môn Tin Học đạt kết quả cao

- Tạo ra nguồn tài liệu tham khảo về thuật toán hỗ trợ cho học sinh, giáoviên dạy Tin học bậc THPT

- Sử dụng NNLT C++ trong chương trình giáo dục phổ thông mới

Trang 3

1.3 Đối tượng nghiên cứu

Sáng kiến kinh nghiệm có đối tượng nghiên cứu là các thuật toán sắp xếp

và viết một số chương trình có sử dụng các thuật toán sắp xếp bằng NNLT C++

1.4 Phương pháp nghiên cứu

Để trình bày sáng kiến kinh nghiệm này, chúng tôi đã sử dụng phối kết hợpnhiều phương pháp như: nghiên cứu tài liệu, thuyết trình, quan sát, điều tra cơbản, thực nghiệm so sánh, phân tích kết quả thực nghiệm, vận dụng… phù hợpvới môn học thuộc lĩnh vực Tin học

Trang 4

2 NỘI DUNG NGHIÊN CỨU

2.1 Cơ sở lý luận

Nếu học sinh thực hiện tốt việc lựa chọn và cài đặt chương trình tối ưu khigiải các bài toán sắp xếp nói riêng và các bài tập lập trình nói chung thì chất

lượng học sinh giỏi sẽ được nâng cao

Học sinh dần được làm quen với NNLT C++

2.2 Thực trạng

2.2.1 Thực trạng trước khi nghiên cứu

Đối với thi học sinh giỏi, dù kết quả output của 2 thí sinh có giống hệt nhauvới cùng một bộ input, nhưng việc chênh lệch về thời gian quyết định thí sinh cóthể chiến thắng hay thất bại (yêu cầu thời gian xử lí chương trình không quá 1giây/1 test) Lý do khi vận dụng các thuật toán thì thường học sinh chỉ chọnnhững thuật toán quen thuộc mà ít khi phân tích bài toán để tìm ra thuật toánphù hợp hơn

Vấn đề đặt ra, là làm thế nào để lấy được điểm với các bộ input có dữ liệulớn Muốn vậy cần phải lựa chọn và cài đặt được chương trình hiệu quả (tối ưu).Chương trình hiệu quả là chương trình giải quyết được những bộ input có dữliệu lớn, chính xác, dung lượng sử dụng bộ nhớ nhỏ, thời gian thực chương trìnhngắn,

2.3 Các biện pháp sử dụng để giải quyết vấn đề

2.3.1 Giới thiệu về bài toán sắp xếp

2.3.1.1 Khái niệm

Sắp xếp là quá trình xử lý một danh sách các phần tử (hoặc các mẫu tin)

để đặt chúng theo một thứ tự, thỏa mãn một tiêu chuẩn nào đó dựa trên nội dungthông tin lưu trữ tại mỗi phần tử

Ví dụ: cho trước một dãy số a1, a2, , an được lưu trữ trong cấu trúc dữ liệumảng

Sắp xếp dãy số a1, a2, , an là thực hiện việc bố trí lại các phần tử sao cho đượcdãy mới có thứ tự tăng dần (hoặc giảm dần)

Hai thao tác so sánh và gán là các thao tác cơ bản của hầu hết các thuậttoán sắp xếp Bài toán sắp xếp xuất hiện trong bất kỳ lĩnh vực nào của tin học

Khi xây dựng một bài toán sắp xếp, cần tìm cách giảm thiểu những phép

so sánh và đổi chỗ không cần thiết để tăng hiệu quả của thuật toán

Trong đề tài này tôi giới thiệu một số giải thuật sắp xếp từ đơn giản đếnphức tạp có thể áp dụng thích hợp cho việc sắp xếp

Trang 5

2.3.1.2 Mục đích của sắp xếp

Mục đích của việc sắp xếp chính là giúp chúng ta có cái nhìn tổng quanhơn về những dữ liệu mà ta có, dễ dàng tìm kiếm những phần tử đứng thứ nhất

về một tiêu chí nào đó

2.3.2 Một thuật toán sắp xếp cơ bản

2.3.1.1 Sắp xếp nổi bọt (Bubble Sort)

2.3.1.1.1 Ý tưởng của thuật toán

Sắp xếp nổi bọt là thuật toán đơn giản nhất, ý tưởng thuật toán này như sau:Duyệt qua danh sách, làm cho các phần tử lớn nhất hoặc nhỏ nhất về cuốidanh sách, tiếp tục làm phần tử lớn hơn hoặc nhỏ hơn cận kề đó dịch chuyển vềcuối cứ như thế cho đến hết danh sách

2.3.1.1.2 Nội dung và cài đặt chương trình

Các bước thực hiện giải thuật:

1 Gán i 0

2 Gán j 0

3 Nếu A[j] > A[j+1] thì đổi chỗ A[j] và A[j+1]

4 Nếu j < n-j-1:

4.1: Đúng thì j=j+1 và quay lại bước 3

4.2: Sai thì sang bước 5

Trang 6

for (int i=0;i<=n-2;i++)

for (int j=i+1;j<=n-1;j++)

if (a[i]>a[j])

{

swap(a[i],a[j]);

}

//in ket qua

for (int i=0;i<=n-1;i++)

2.3.1.1.3 Đánh giá độ phức tạp của thuật toán

Ta nhận thấy trong giải thuật Bubble số lượng các phép so sánh khôngphụ thuộc vào trạng thái ban đầu của dãy cần sắp xếp, nhưng số hoán vị lại phụthuộc vào trạng thái ban đầu của dãy

Sắp xếp nổi bọt là một thuật toán sắp xếp ổn định

Về độ phức tạp, do dùng hai vòng lặp lồng nhau nên độ phức tạp thời giantrung bình của thuật toán này là O(n2)

2.3.1.2 Sắp xếp chọn (Selection Sort)

2.3.1.2.1 Ý tưởng của thuật toán

Ý tưởng của thuật toán này như sau:

Duyệt từ phần tử đầu đến phần tử kề cuối danh sách, duyệt tìm phần tửnhỏ nhất từ vị trí kề phần tử đang duyệt đến hết, sau đó đổi vị trí của phần tử

Trang 7

nhỏ nhất đó với phần tử đang duyệt và cứ tiếp tục như vậy.

2.3.1.2.2 Nội dung và cài đặt chương trình

Các bước thực hiện giải thuật:

B5: Nếu i < n-1 thì i i+1 và quay lại B2

Trang 8

//in ket qua

for (int i=0;i<=n-1;i++)

2.3.1.2.3 Đánh giá độ phức tạp của thuật toán

Ta nhận thấy ở lượt thứ i, để chọn ra phần tử nhỏ nhất bao giờ cũng cần

n-i phép so sánh Số lượng phép so sánh trong thuật toán này không phụ thuộc vàotình trạng ban đầu của mảng

Về độ phức tạp, do dùng hai vòng lặp lồng nhau nên độ phức tạp thời giantrung bình của thuật toán này là O(n2)

2.3.1.3 Sắp xếp chèn (Insert Sort)

2.3.1.3.1 Ý tưởng của thuật toán

Ý tưởng của thuật toán là chèn phần tử thứ i + 1 vào i phần tử đầu tiên củadãy đã có thứ tự để được dãy mới trở nên có thứ tự Việc chèn thực hiện nhưsau: Tiến hành tìm vị trí của phần tử i+1 trong k phần tử đầu tiên bằng cách vậndụng giải thuật tìm kiếm, sau khi tìm được vị trí chèn thì chúng ta sẽ tiến hànhchèn phần tử i+1 bằng cách dời các phần tử từ vị trí chèn đến phần tử thứ i sang

Trang 9

phải 1 vị trí và chèn phần tử i+1 vào vị trí đó.

2.3.1.3.2 Nội dung và cài đặt chương trình

Các bước thực hiện của thuật toán:

B1: i 1

B2: x A[i]; pos i-1

B3: Nếu Pos >= 0 và A[pos] > x:

B3.1:A[Pos+1] A[Pos]

B3.2: Pos Pos-1;

B3.3: Quay lại B3B4: A[Pos+1] x

B5: Nếu i < n thì i i+1 và quay lại B2

Trang 10

//in ket qua

for (int i=0;i<=n-1;i++)

2.3.1.3.3 Đánh giá độ phức tạp của thuật toán

Đối với giải thuật sắp xếp kiểu chèn, các phép so sánh xảy ra trong mỗivòng lặp While là tìm vị trí chèn thích hợp j Mỗi lần xác định vị trí đang xétkhông thích hợp, sẽ dời chỗ phần tử a[j] tương ứng Giải thuật thực hiện tất cảN-1 vòng lặp While Số lượng phép so sánh và phép dời chỗ này phụ thuộc vàotình trạng của dãy số ban đầu

Về độ phức tạp, do dùng hai vòng lặp lồng nhau nên độ phức tạp thời giantrung bình của thuật toán này là O(n2)

2.3.1.4 Thuật toán Shell Sort

2.3.1.4.1 Ý tưởng của thuật toán

Shell sort là một giải thuật sắp xếp mang lại hiệu quả cao dựa trên giải thuậtsắp xếp chèn (Insertion Sort) Giải thuật này tránh các trường hợp phải tráo đổi

vị trí của hai phần tử xa nhau trong giải thuật sắp xếp chọn (Nếu như phần tửnhỏ hơn ở vị trí bên phải khá xa so với phần tử lớn hơn bên trái)

Trang 11

Giải thuật này sử dụng giải thuật sắp xếp chọn trên các phần tử có khoảngcách xa nhau, sau đó sắp xếp các phần tử có khoảng cách hẹp hơn.

2.3.1.4.2 Nội dung và cài đặt chương trình

Trang 12

2.3.1.4.3 Đánh giá độ phức tạp của thuật toán

Đây là giải pháp khá hiệu quả với các tập dữ liệu có kích thước trung bìnhkhi mà độ phức tạp trường hợp xấu nhất và trường hợp trung bình là O(n2)

2.3.1.5 Sắp xếp kiểu phân đoạn (QuickSort)

2.3.1.5.1 Ý tưởng của thuật toán

Sắp xếp nhanh (QuickSort) hay sắp xếp phân đoạn (Partition) là thuật toánsắp xếp dựa trên kỹ thuật chia để trị, cụ thể ý tưởng là: chọn một điểm làm chốt(gọi là pivot), sắp xếp mọi phần tử bên trái chốt đều nhỏ hơn chốt và mọi phần

tử bên phải đều lớn hơn chốt, sau khi xong ta được 2 dãy con bên trái và bênphải, áp dụng tương tự cách sắp xếp này cho 2 dãy con vừa tìm được cho đếnkhi dãy con chỉ còn 1 phần tử

2.3.1.5.2 Nội dung và cài đặt chương trình

Thuật toán như sau:

B1: Chọn một phần tử làm chốt

B2: Sắp xếp phần tử bên trái nhỏ hơn chốt

B3: Sắp xếp phần tử bên phải nhỏ hơn chốt

B4: Sắp xếp hai mảng con bên trái và bên phải pivot

Phần tử được chọn làm chốt rất quan trọng, nó quyết định thời gian thực

Trang 13

thi của thuật toán Phần tử được chọn làm chốt tối ưu nhất là phần tử trung vị,phần tử này làm cho số phần tử nhỏ hơn trong dãy bằng hoặc xấp xỉ số phần tửlớn hơn trong dãy Tuy nhiên, việc tìm kiếm này rất tốn kém, phải có thuật toántìm kiếm riêng, từ đó làm giảm hiệu suất của thuật toán tìm kiếm nhanh, do đó,

để đơn giản, người ta sử dụng phần tử chính giữa làm chốt

Trang 14

2.3.1.5.3 Đánh giá độ phức tạp của thuật toán

Hiệu quả của giải thuật Quick Sort phụ thuộc vào việc chọn khóa chốt đểphân đoạn Trường hợp tốt nhất xảy ra nếu mỗi lần phân đoạn đều chọn đượckhóa chốt lớn hơn (hoặc bằng) nửa số phần tử, và nhỏ hơn (hoặc bằng) nửa sốphần tử còn lại; khi đó độ phức tạp tính toán của Quick Sort là O(nlogn) Nhưngnếu mỗi lần chọn khóa chốt để phân đoạn lại chọn nhằm phần tử có giá trị cựcđại (hay cực tiểu) là khóa chốt, dãy sẽ bị chia thành hai phần không đều: mộtphần chỉ có 1 phần tử, phần còn lại có n-1 phần tử thì lúc đó cần n lần phân đoạn

Trang 15

mới sắp xếp xong Lúc đó độ phức tạp của Quick Sort là O(n2) Vì vậy thời gianthực hiện giải thuật Quick Sort trung bình là O(nlogn).

2.3.1.6 Sắp xếp bằng phép đếm phân phối (Counting Sort)

2.3.1.6.1 Ý tưởng của thuật toán

Counting sort là một thuật toán sắp xếp cực nhanh một mảng các phần tử

mà mỗi phần tử là các số nguyên không âm; hoặc là một danh sách các ký tựđược ánh xạ về dạng số để sort theo bảng chữ cái Counting sort là một thuậttoán sắp xếp các con số nguyên không âm, không dựa vào so sánh

2.3.1.6.2 Nội dung và cài đặt chương trình

Trang 16

for (int i=1;i<k;i++)

//in ket qua

for (int i=0;i<=n-1;i++)

fo<<a[i]<<" ";

fi.close();fo.close();

return 0;

}

2.3.1.6.3 Đánh giá độ phức tạp của thuật toán

Trong khi các thuật toán sắp xếp tối ưu sử dụng so sánh có độ phức tạpO(nlogn) thì Counting sort chỉ cần O(n) nếu độ dài của danh sách không quánhỏ so với phần tử có giá trị lớn nhất

2.3.1.7 Sắp xếp kiểu vun đống (Heap sort)

2.3.1.7.1 Ý tưởng của thuật toán

Giải thuật Heap sort còn được gọi là giải thuật vun đống, có thể được xemnhư bản cải tiến của Selection Sort khi chia các phần tử thành 2 mảng con:

Trang 18

//in ket qua

for (int i=0;i<n;++i)

fo<<a[i]<<" ";

fo<<"\n";

clock_t end=clock();

Trang 19

fo<<"time run:"<<(float) (end-begin)/CLOCKS_PER_SEC<<" s";

fi.close();fo.close();

return 0;

}

2.3.1.7.3 Đánh giá độ phức tạp của thuật toán

Heap Sort là giải thuật đảm bảo trong trường hợp xấu nhất, độ phức tạpgiải thuật cũng là O(nlogn) Giải thuật này cũng không cần thêm các cấu trúc dữliệu phụ trợ trong quá trình thực thi, do đó sẽ có tốc độ nhanh và thường được sửdụng rộng rãi do không khó để thực hiện

2.3.1.8 Sắp xếp trộn (Merge Sort)

2.3.1.8.1 Ý tưởng của thuật toán

Sắp xếp trộn (merge sort) là một thuật toán dựa trên kỹ thuật chia để trị, ýtưởng của thuật toán này như sau: chia đôi mảng thành hai mảng con, sắp xếphai mảng con đó và trộn lại theo đúng thứ tự, mảng con được sắp xếp bằng cáchtương tự

2.3.1.8.2 Nội dung và cài đặt chương trình

Giả sử left là vị trí đầu và right là cuối mảng đang xét, cụ thể các bướccủa thuật toán như sau:

Nếu mảng còn có thể chia đôi được (left<right)

Trang 20

int n2=right-mid;

int* L=new int[n1];

int* R=new int[n2];

for (int ii=0;ii<n1;ii++)

Trang 21

void mergesort(int arr[],int left, int right)

//in ket qua

for (int i=0;i<=n-1;i++)

Trang 22

2.3.1.8.3 Đánh giá độ phức tạp của thuật toán

Về độ phức tạp, thuật toán Merge Sort có độ phức tạp thời gian trung bình

là O(nlog(n)), về không gian, do sử dụng mảng phụ để lưu trữ và 2 mảng phụdài nhất là hai mảng phụ ở lần chia đầu tiên có tổng số phần tử đúng bằng sốphần tử cùa mảng nên độ phức tạp sẽ là O(n) Sắp xếp trộn là thuật toán sắp xếp

ổn định

2.3.3 Đánh giá thuật toán và những yếu tố cần quan tâm khi sử dụng thuật toán

2.3.3.1 Đánh giá thuật toán

Trong chương trình cài đặt các thuật toán sắp xếp ở trên, trong chươngtrình tôi tính luôn thời gian chạy chương trình trong tệp ra để dễ so sánh

Trường hợp 1: Với 5 bộ test ngẫu nhiên các phần tử, bảng so sánh thời gian thực hiện của các thuật toán như sau:

Phân tích kết quả: từ bảng so sánh thời gian chạy ở trên ta có thể thấy

những giải thuật có độ phức tạp O(n2) thì thời gian chạy vẫn nhiều nhất, tuynhiên nó vẫn là thời gian chấp nhận được đối với 1 giải thuật (chưa quá 1s).Những thuật toán có độ phức tạp O(n) hoặc O(nlogn) thì thời gian chạy nhanhhơn Tuy nhiên đối với Counting Sort mặc dù thời gian chạy nhanh nhưngkhông phù hợp với bộ test ngẫu nhiên (các phần tử có thể âm)

Trường hợp 2: Với 5 bộ test mà các phần tử dương, số lượng phần tử

<=10000

Độ phức

Trang 23

Phân tích kết quả: Ở bảng kết quả này ta có thể thấy độ chênh lệch thời

gian giữa các nhóm thuật toán

Các thuật toán có độ phức tạp O(n2) có vẻ không ổn khi dữ liệu vào lớn

Thuật toán Counting đứng top đầu về thời gian chạy Dữ liệu càng lớn thì càngthấy rõ tính tối ưu của Counting Sort

Những thuật toán có độ phức tạp O(nlogn) và O(n) vẫn ổn định khi dữ liệu vàolớn

Trường hợp 3: Với 5 bộ test mà các phần tử dương, số lượng phần tử

Phân tích kết quả: Ở trường hợp này, thuật toán Counting Sort vẫn đang

chứng minh là thuật toán ổn nhất Tiếp theo đó là Quick Sort, Heap Sort, MergeSort

2.3.3.2 Những yếu tố cần quan tâm khi sử dụng thuật toán

Từ những phân tích trên ta nhận thấy, cùng một mục đích sắp xếp nhưnhau nhưng có nhiều phương pháp giải quyết khác nhau Nếu chỉ dựa vào thờigian tính toán của thuật toán đo được trong một ví dụ cụ thể mà đánh giá giải

Ngày đăng: 21/05/2021, 22:13

Nguồn tham khảo

Tài liệu tham khảo Loại Chi tiết
[1] Ngôn ngữ lập trình C++, Đặng Trung Kiên, giáo viên THPT Chuyên Lê Hồng Phong Sách, tạp chí
Tiêu đề: Ngôn ngữ lập trình C++
[2] Bài giảng chuyên đề, Lê Minh Hoàng Sách, tạp chí
Tiêu đề: Bài giảng chuyên đề
[3] Tài liệu chuyên tin quyển 1, Hồ Sĩ Đàm (chủ biên), Đỗ Đức Đông, Lê Minh Hoàng, Nguyễn Thanh Hùng, NXB Giáo Dục Việt Nam Sách, tạp chí
Tiêu đề: Tài liệu chuyên tin quyển 1
Nhà XB: NXB Giáo Dục Việt Nam
[4] Trang web: https://vn.spoj.com/ Link
[5] Trang web: https://codelearn.io/ Link

TỪ KHÓA LIÊN QUAN

TÀI LIỆU CÙNG NGƯỜI DÙNG

TÀI LIỆU LIÊN QUAN

🧩 Sản phẩm bạn có thể quan tâm

w