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.. Thủ tục DownHeap trong giả mã dưới đây Vun một mảng thành đống Để
Trang 1ĐẠI HỌC QUỐC GIA THÀNH PHỐ HỒ CHÍ MINH
CHƯƠNG TRÌNH ĐÀO TẠO THẠC SĨ CNTT
Tiểu luận : MÔ PHỎNG THUẬT TOÁN
HEAPSORT & QUICK SORT TRÊN
MAPLE
Giảng viên hướng dẫn : PGS.TS Đỗ Văn Nhơn Học viên thực hiện : Đoàn Vũ Ngọc Duy MSSV : CH1101010
Trang 3I Thuật toán Heapsort
1 Mô tả bài toán
Mỗi mảng a[1 n] có thể xem như một cây nhị phân gần đầy (có trọng số là các giá trị của mảng), với gốc ở phần tử thứ nhất, con bên trái của đỉnh a[i] là a[2*i] con bên phải là a[2*i+1] (nếu mảng bắt đầu từ 1 còn nếu mảng bắt đầu từ 0 thì 2 con là a[2*i+1] và a[2*i+2] ) (nếu 2*i<=n hoặc 2*i+1<=n, khi đó các phần tử có
chỉ số lớn hơn không có con, do đó là lá)
Ví dụ mảng (45,23,35,13,15,12,15,7,9) là một đống
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 nhi 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 Một đống cực tiểu được định nghĩa theo các bất đẳng thức ngược lại: a[i]<=a[2*i] và a[i]<=a[2*i+1] Phần tử đứng ở gốc cây cực tiểu là phần tử nhỏ nhất
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 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],
Trang 4tiế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á (Thủ tục DownHeap trong giả mã dưới đây)
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) kho qua 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ử
2 Thuật giải
Giai đoạn 1: Hiệu chỉnh dãy số ban đầu thành Heap
Giai đoạn 2: Sắp xếp dãy số dựa trên Heap
Bước 1 : Đưa phần tử lớn nhất về vị trí đứng ở cuối dãy
r = n;
Hoán vị (a1,ar)
Bước 2: Loại bỏ phần tử lớn nhất ra khỏi Heap r = r - 1;
Trang 5Hiệu chỉnh phần còn lại của dãy từ al đến ar thành một Heap.
Bước 3 : Nếu r >1 ( heap còn phần tử) : lặp lại bước 2
Ngược lại : dừng
Dựa vào tính chất 3, ta có thể thực hiện giai đoạn 1 bằng cách bắt đầu từ heap mặc nhiên an/2+1, an/2+2,…,an, lần lượt thêm vào các phần tử an/2, an/2-1,
…,a1 ta sẽ nhận được Heap theo mong muốn Như vậy giải đoạn 1 tương đương với n/2 lần thực hiện bước 2 của giai đoạn 2
3 Giải bài toán trên maple
> parent:=i->floor(i/2);
>
>
Trang 6>
>
Trang 7>
>
>
>
>
>
>
>
Trang 8>
>
>
>
>
>
>
>
>
1 Mô tả bài toán
Trang 9Sắp xếp nhanh (Quicksort), còn được gọi là sắp xếp kiểu phân chia (part sort) là một thuật toán sắp xếp phát triển bởi C.A.R Hoare, dựa trên phép phân chia danh sách được sắp thành hai danh sách con Phương pháp này là minh họa rõ ràng nhất Để sắp xếp một danh sách a[1…n] ta chia nó thành hai danh sách bằng cách so sánh từng phần tử của danh sách với một phần tử được chọn làm phần tử chốt
Những phần tử nhỏ hơn phần tử chốt được đưa về phía trước và nằm trong danh sách con thứ nhất, các phần tử lớn hơn chốt được đưa về phía sau và thuộc danh sách đứng sau Cứ tiếp tục chia như vậy tới khi các danh sách con đều có độ dài bằng 1
Danh sách a[1…n]:
Danh sách 1 gồm: a[1…k] < X
Danh sách 2 gồm: a[(k+1) …n] > X
a < X
a = X
a > X
Ở đây ta thấy xuất hiện 3 danh sách con, trong đó:
Danh sách thứ 2 đã được sắp xếp Nếu danh sách 1 và 3 chỉ có một phần tử thì dãy a[i…n] đã được sắp xếp xong Nếu danh sách 1 và 3 có hơn một phần tử thì dãy ban đầu chỉ có thứ tự khi các dãy con 1, 3 được sắp Để sắp xếp dãy con 1 và
3, ta lần lượt tiến hành việc phân hoạch từng dãy con theo cùng phương pháp phân hoạch dãy ban đầu vừa trình bày
4 Thuật giải
Giải thuật phân hoạch dãy a[1…n] thành hai dãy con gồm 3 bước:
Trang 10Bước 1: chọn tùy ý 1 phần tử a[k] trong dãy làm giá trị mốc.
L ≤ k ≤ R : a[k] =X;
i = L; j = R;
Gợi ý các cách chọn phần tử mốc
Chọn phần tử đứng đầu hoặc đứng cuối làm phần tử chốt
Chọn phần tử đứng giữa danh sách làm phần tử chốt
Chọn phần tử trung vị trong 3 phần tử đứng đầu, đứng giữa và đứng cuối làm phần tử chốt
Chọn phần tử ngẫu nhiên làm phần tử chốt (Cách này có thể dẫn đến khả năng rơi vào các trường hợp đặc biệt)
Bước 2: Phát hiện và hiệu chỉnh cặp phần tử a, a[j] nằm sai chỗ:
Bước 2a: Trong khi (a < X) i++;
Bước 2b: Trong khi (a[j] > X) j++;
Bước 2c: Nếu i < j // a ≥ X ≥ a[j] mà a[j] đứng sau a
Hoán vị ( a, a[j]);
Bước 3: Nếu i < j; Lặp lại Bước 2
// chưa xét hết mảng
Nếu I > j; Dừngcho chiến lược chia để trị
5 Giải bài toán trên Maple
Trang 11>
Trang 12>
>
>
>
Trang 13>
>
>
>
>
>
>
>
Trang 14>
>
>
>
>