Chuyen de Sap Xep

You might also like

Download as doc, pdf, or txt
Download as doc, pdf, or txt
You are on page 1of 2

Bài 2: SẮP XẾP

1. Khái niệm:
- Sắp xếp là một quá trình tổ chức lại 1 dãy dữ liệu theo 1 trật tự nhất định.
- Mục đích: giúp cho việc tìm kiếm dữ liệu được dễ dàng và nhanh; dùng trong phương phám
tham lam.
2. Phân loại: - SX trong: SX mảng đưa vào bộ nhớ trong  dữ liệu nhỏ <Ram
- SX ngoài: SX tệp  dữ liệu > Ram
3. Một số phương pháp:
a. SX đơn giản:
* Hướng dẫn giải thuật:
- Bắt đầu từ phần tử đầu tiên của dãy, so sánh với các phần tử còn lại, nếu không thõa mãn điều
kiện sắp xếp thì hoán đổi 2 phần tử đó cho nhau, cứ tiếp tục như vậy cho đến phần tử cuối cùng.
- Cụ thể: khi sắp xếp mảng A[1..n] tăng dần ta sử dụng 2 vòng lặp lồng nhau với 2 biến điều khiển
i, j:
For i:=1 to n-1 do
For j:=i+1 to n do
Nếu A[i]>A[j] thì Hoán đổi A[i], A[j]
b. Sắp xếp nhanh (Quicksort): Giả sử cần sắp mảng A tăng dần
* Hướng dẫn giải thuật:
- Chia dãy cần sắp thành 2 phần, lấy giá trị giữa X làm chuẩn để so sánh
- Đi tìm 1 phần tử A ở dãy trước có giá trị lớn hơn X
- Đi tìm 1 phần tử B ở dãy sau có giá trị nhỏ hơn X
- Hoán đổi A, B
- Tiếp tục như vậy cho đến khi ta đạt được dãy trước chứa các giá trị <X, dãy sau >X
- Tiếp tục áp dụng các bước trên cho các dãy con trước và sau cho đế khi không chia được nữa thì
việc SX đã hoàn tất.
Cụ thể: Xét đoạn của dãy từ thành phần thứ L đến R ta thực hiện
+ Lấy giá trị giữa gán cho X (X:=A[(L+R) div 2])
+ Cho i ban đầu L
+ Cho j ban đầu R
+ Lặp lại:
- Chừng nào còn A[i]<X thì tăng i;
- Chừng nào còn A[j]>X thì giảm j;
- Nếu i<=j thì:
Hoán đổi A[i], A[j]
Tăng i
Giảm j
Cho đến khi i>j
+ Nếu i<R thì Sắp đoạn từ A[i] đến A[R]
+ Nếu L<j thì Sắp đoạn từ A[L] đến A[j]
* Chương trình mẫu:
Procedure Qsort(Var A:mang; L,R:integer);
Var i,j:integer; X, tg:longint;
Begin
X:=A[(L+R) div 2];
I:=l;j:=R;
Repeat
While A[i]<X do inc(i);
While A[j]>X do dec(j);
If i<=j then Begin tg:=A[i]; A[i]:=A[j]; A[j]:=tg; Inc(i);Dec(j); End;
Until i>j;
If L<j then Qsort(A,L,j);
If i<R then Qsort(A,i,R);
End;
BEGIN Qsort(A,1,n);
END.
* Nhận xét: tốc độ nhanh, trường hợp xấu nhất: phân hoạch thành 2 dãy trong đó 1 dãy chỉ 1 phận
tử, dãy còn lại n-1 phần tử.
4. Một số bài toán áp dụng:
Ví dụ 1: Giá trị nhỏ thứ k:
Cho dãy a1, a2, … , an. Các số đô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.
* Hướng dẫn:
- SX dãy tăng dần
- Số nhỏ thứ k chính là số thứ k của dãy đã SX (A[k]).
Ví dụ 2: Thống kê
Cho dãy 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: 6 7 1 7 4 6 6 8 thì dãy có 5 số khác nhau và số lần lặp nhiều nhất là 3 (số 6)
* Hướng dẫn:
- Sắp xếp dãy tăng dần (hoặc giảm dần)
- Đếm số lượng giá trị khác nhau: Đếm cặp số gần nhau có giá trị khác nhau: A[i]<>A[i+1]
Count:=1;
For i:=2 to n do If A[i]<>A[i-1] then inc(count);
- Đếm số lần nhiều nhất:
Count:=1; maxcount:=1;
For i:=2 to n do
Begin If A[i]<>A[i-1] then count:=1 Else inc(count);
If count>maxcount then maxcount:=count;
End;
Ví dụ 3: tìm số tự nhiên nhỏ nhất chưa có trong dãy
Cho dãy gồm N (N<=30000) số tự nhiên không vượt quá 10 9, tìm số tự nhiên nhỏ nhất không xuất
hiện trong dãy.
* Hướng dẫn:
- Sắp xếp tăng dần
- Tìm số tự nhiên nhỏ nhất chưa xuất hiện: duyệt từ số thứ 2 trở đi nếu số sau khác số đứng trước
+1 thì số cần tìm là: giá trị số đứng trước +1.
If A[1]<>1 then sotim:=1 Else For i:= 2 to n+1 do If A[i] <> A[i-1]+1 then begin sotim:= A[i-
1]+1; Break; end;
Cách khác: Khai báo mảng 30000 phần tử nguyên dương, sau đó đếm tần suất xuất hiện của các số
trong dãy.
Ví dụ 4: Cho mảng 2 chiều Amxn sắp xếp lại mảng tăng dần
* Hướng dẫn:
- Đọc ra mảng 1 chiều C[1..mxn]: For i:=1 to m do For j:=1 to n do C[(i-1)*n+j]:=A[i,j];
- SX mảng C
- Điền lại vào mảng A: For i:= 1 to m do For j:=1 to n do A[i,j]:= C[(i-1)*n+j];

You might also like