1 [Hướng dẫn]Sắp xếp vun đống Tue May 31, 2011 10:33 am
Admin
Quản trị viên
Cần lưu ý:
- Không nói gì, ngầm định là đống không tăng theo định nghĩa, còn trường hợp đống không giảm, đề sẽ nói rõ.
- Không nói gì, ngầm định là đống được lưu trữ vào dạng mảng danh sách. Lần lượt từ trái sang phải, hết mức nọ đến mức kia. Hết hàng nọ đến hàng kia.
Về chỉ số: Nếu i chỉ ra nút bất kì, tuy nhiên i ≤ n/2, thì :
- Con trái có chỉ số là: 2i
- Con phải có chỉ số là: 2i+1
- Khi nói con chung chung, ngầm định là con trái.
Một cây nhị phân, được gọi là đống cực đại nếu khóa của mọi nút không nhỏ hơn khóa các con của nó. Khi biểu diễn một mảng a[] bởi một cây nhị phân theo thứ tự tự nhiên điều đó nghĩa là a[i] ≥ a[2*i] và a[i] ≥ a[2*i +1] với mọi i =1..int(n/2). Ta cũng sẽ gọi mảng như vậy là đống. Như vậy trong đống a[1] (ứng với gốc của cây) là phần tử lớn nhất. Mảng bất kỳ chỉ có một phần tử luôn luôn là một đống.
Vun đống
Việc sắp xếp lại các phần tử của một mảng ban đầu sao cho nó trở thành đống được gọi là vun đống.
Vun đống tại đỉnh thứ i
Nếu hai cây con gốc 2 * i và 2 * i +1 đã là đống thì để cây con gốc i trở thành đống chỉ việc so sánh giá trị a[i] với giá trị lớn hơn trong hai giá trị a[2 * i] và a[2 * i + 1], nếu a[i] nhỏ hơn thì đổi chỗ chúng cho nhau. Nếu đổi chỗ cho a[2 * i], tiếp tục so sánh với con lớn hơn trong hai con của nó cho đến khi hoặc gặp đỉnh lá.
Vun một mảng thành đống
Để vun mảng a[1..n] thành đống ta vun từ dưới lên, bắt đầu từ phần tử a[j]với j =Int(n/2) ngược lên tới a[1]. (Thủ tục MakeHeap trong giả mã dưới đây).
Sắp xếp bằng vun đống
Đổi chỗ (Swap): Sau khi mảng a[1..n] đã là đống, lấy phần tử a[1] trên đỉnh của đống ra khỏi đống đặt vào vị trí cuối cùng n, và chuyển phần tử thứ cuối cùng a[n] lên đỉnh đống thì phần tử a[n] đã được đứng đúng vị trí.
Vun lại: Phần còn lại của mảng a[1..n-1] chỉ khác cấu trúc đống ở phần tử a[1]. Vun lại mảng này thành đống với n-1 phần tử.
Lặp: Tiếp tục với mảng a[1..n-1]. Quá trình dừng lại khi đống chỉ còn lại một phần tử.
Lưu ý khi đọc đề và làm bài:
- Khi đề bài ra như sau: Cho mảng X{X1, X2...Xn}, trong đó các giá trị X1, X2..Xn là các số cho sẵn.
- Hỏi: Chứng minh rằng đây không phải là đống, hoặc xác định xem X có phải là đống không. Thì khi làm chỉ cần chỉ ra 2 phần tử không thuộc tính chất của đống. Sau đó khẳng định luôn nó không phải là đống. Còn nếu khẳng định X là đống thì chứng minh theo tính chất của đống là với mọi chỉ số i <i ≥ X2i và Xi ≥ X2i+1. Khi đề không yêu cầu viết chương trình giả mã, thì chỉ việc vẽ các bước để sắp xếp thành đống.
Ví dụ đề ra như sau:
Cho dãy X10 {12, 4, 8, 17,6, 5, 21, 33, 22, 20}
Hãy kiểm tra X có thoả mãn điều kiện là một đống không? Nếu không, hãy sắp xếp X sao cho là một đống.
Cách làm:
1. Kiểm tra X có thoả mãn điều kiện là một đống không?
Ta thấy với i = 1 thì Xi = X1 = 12, X2i = X2 = 4, X2i+1 = X3 = 8 thoả mãn tính chất Xi ≥ X2i và Xi ≥ X2i
Với i = 2 thì Xi = X2 = 4, X2i = X4 = 17, X2i+1 = X5 = 6 không thoả mãn tính chất Xi ≥ X2i và Xi ≥ X2i
Từ 2 trường hợp trên, kết luận X không phải là đống.
2. Sắp xếp X sao cho thành đống.
(Thực hiện vẽ đống theo từng công đoạn đổi chỗ Xi và các con của nó). Lưu ý Xi mà nhỏ hơn cả 2 con của nó, thì vẽ đổi chỗ cho con trái trước, sau đó mới đổi chỗ cho con phải. Vẽ theo thứ tự sau:
- Đổi chỗ ở nhánh bên phải nhất hàng cuối cùng → Đổi chỗ sang bên trái -→ hàng kế tương tự.
Thuật toán và giả mã:
Có nhiều sách viết, nhưng thống nhất theo cách viết thầy dạy, đừng có mà í ới theo các sách viết khác để nhầm lẫn là không có điểm đâu nha.
Thủ tục con vun đống:
Proc VĐ1(k: Chỉ số gốc, Temp: Giá trị chờ, m: chỉ số nút cuối cùng)
1. Stop = false;
2. While 2k < m & !Stop
a. j: = 2k
if ((j+1) ≤ m) & (Xj ≤ Xj+1) then j := j + 1;
b. if Xj > Temp then {Xk : = Xj ; k = j}
else Stop := true;
3. Xk: = Temp
Thủ tục tạo đống (sẽ gọi thủ tục vun đống nhiều lần đến khi đạt được mục đích thì thôi):
Proc Tạo đống;
n:=/X/
1. for i:= INT(n/2) downto 1 VĐ1(i, Xi, n)
2. For m := n - 1 downto 1
Temp := Xm+1;
VĐ1(1, Temp, m)
Xm+1 = Temp;
3. Output X
Anh Admin xem lại Tạo đống nhé, thuật toán này thày viết nhưng chưa đúng đâu
Em Son
Giải thuật của thầy còn thiếu (em đọc sách thầy Lôi em thấy thế), sách thầy Lôi dễ hiểu hơn nhiều.
Được sửa bởi Admin ngày Mon Jul 11, 2011 10:46 am; sửa lần 4. (Reason for editing : Theo bài học và lời dặn của thầy)