Ebooks, Audobooks and Classical Music from Liber Liber
a b c d e f g h i j k l m n o p q r s t u v w x y z





Web - Amazon

We provide Linux to the World


We support WINRAR [What is this] - [Download .exe file(s) for Windows]

CLASSICISTRANIERI HOME PAGE - YOUTUBE CHANNEL
SITEMAP
Audiobooks by Valerio Di Stefano: Single Download - Complete Download [TAR] [WIM] [ZIP] [RAR] - Alphabetical Download  [TAR] [WIM] [ZIP] [RAR] - Download Instructions

Make a donation: IBAN: IT36M0708677020000000008016 - BIC/SWIFT:  ICRAITRRU60 - VALERIO DI STEFANO or
Privacy Policy Cookie Policy Terms and Conditions
Sắp xếp nhanh – Wikipedia tiếng Việt

Sắp xếp nhanh

Bách khoa toàn thư mở Wikipedia

Sắp xếp nhanh (Quicksort), còn được gọi là sắp xếp kiểu phân chia (part sort), dựa trên phép phân chia danh sách được sắp thành hai danh sách con. Khác với sắp xếp trộn, chia danh sách cần sắp xếp a[1..n] thành hai danh sách con có kích thước tương đối bằng nhau nhờ chỉ số đứng giữa danh sách, sắp xếp nhanh 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 được gọi là phần tử chốt. Những phần tử nhỏ hơn hoặc bằng 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.

Mục lục

[sửa] Phần tử chốt (pivot)

Kỹ thuật chọn phần tử chốt ảnh hưởng khá nhiều đến khả năng rơi vào các vòng lặp vô hạn đối với các trường hợp đặc biệt. Tốt nhất là chọn phần tử chốt là trung vị của danh sách. Khi đó sau log2(n) lần phân chia ta sẽ đạt tới kích thước danh sách bằng 1. Tuy nhiên điều đó rất khó. Có các cách chọn phần tử chốt như sau:

  • 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.

[sửa] Thuật phân chia

Sau khi phần tử chốt được chọn giải thuật phân chia nên tiến hành như thế nào?

  • Một giải pháp đơn giản nhất cho vấn đề này là duyệt từ đầu đến cuối lần lượt so sánh các phần tử của danh sách với phần tử chốt. Theo cách này, ta phải tiến hành n phép so sánh, ngoài ra còn phải dành n đơn vị bộ nhớ để lưu giữ các giá trị trung gian.
  • Một giải pháp khác được đề nghị là duyệt theo hai đường. Một đường từ đầu danh sách, một đường từ cuối danh sách. Theo cách này, ta tìm phần tử đầu tiên tính từ trái lớn hơn phần tử chốt và phần tử đầu tiên phía phải nhỏ hơn hoặc bằng phần tử chốt rồi đổi chỗ cho nhau. Tiếp tục như vậy cho đến khi hai đường gặp nhau.
  • Để có thể gọi đệ quy ta xét bài toán phân chia một danh sách con của a: a[k1,k2] thành hai danh sách.

[sửa] Ví dụ

Trong ví dụ sau đây ta luôn chọn phần tử chốt là phần tử đứng giữa danh sách với chỉ số của phần tử chốt được chọn là k = int((k1 + k2) / 2) + 1

a = (2,6,3,7,4,5,1)

2 6 3 7 4 5 1

Do ngẫu nhiên, phần tử chốt a[4] = 7 là phần tử lớn nhất trong dãy, ta tìm từ trái sang phải không có phần tử nào lớn hơn phần tử chốt, do đó ta đổi phần tử chốt với phần tử cuối cùng, danh sách được chia thành hai danh sách con a[1..6]a[7..7]

2 6 3 1 4 5 -- 7

Việc phân chia tiếp tục với danh sách cona[1..6]. Phần tử chốt được chọn là a[4]=1. Từ trái sang phải tìm được phần tử đầu tiên lớn hơn a[4] = 1a[1] = 2, từ phải sang phần tử đầu tiên <=1 là chính a[4]. Đổi chố hai phần tử này

1 6 3 2 4 5 -- 7

Đi tiếp sang trái ta được a[2] > 1, ở phía ngược lại đi tiếp sang trái tìm được phần tử nhỏ hơn hoặc bằng chốt là chính a[1] = 1 nhưng lúc này hai đường đã chạm nhau nên ta không đổi nữa. Do vậy a[1..6] được phân chia thầnh hai danh sách con a[1..1]a[2..6]

1 -- 6 3 2 4 5 -- 7

Tiếp tục phân chia a[2..6] với phần tử chốt a[4] = 2 ta được

1 -- 2 -- 3 6 4 5 -- 7

Tiếp tục phân chia a[3..6] với phần tử chốt a[5] = 4 ta được

1 -- 2 -- 3 4 -- 6 5 -- 7

Tiếp tục phân chia a[3..4] với phần tử chốt a[4] = 4a[5..6] với phần tử chốt a[6] = 5 ta được

1 -- 2 -- 3 -- 4 -- 5 -- 6 -- 7

[sửa] Giả mã

[sửa] Thủ tục phân chia

Function Part(a[1..n],k1,k2)

 i=k1;  j=k2;  k=int((k1+k2)/2)+1;  v=a[k]
While i<j do
  While a[i]<=v do i:=i+1;
  While a[j]>v and j>i do j=j-1;
  if i>=k2 then
       Swap(a[k],a[k2])
       return k2-1
    Swap(a[i],a[j])
return i-1

[sửa] Quick Sort đệ quy

Procedure PartSort (a,k1,k2)

 if k1<k2 then
    k=part(a,k1,k2)
   PartSort(a,k1,k)
   PartSort(a,k+1,k2)

[sửa] Khử đệ quy

Nhiều người cho rằng việc khử đệ quy của sắp xếp nhanh thực ra không cần thiết, nó chỉ có tác dụng cho những người mới tiếp cận khoa học máy tính hiểu sâu sắc hơn về khái niệm đệ quy. Bản chất của các giải thuật đệ quy là lưu trữ các tham biến đệ quy vào một ngăn xếp (stack) để lần lượt lấy ra xử lý.

Khi khử đệ quy của giải thuật đệ quy, mỗi lần phân chia danh sách thành 2 danh sách con ta lưu trữ các tham số của danh sách đứng sau vào một ngăn xếp, rồi phân chia tiếp danh sách đứng trước.

Giải thuật đơn giản nhất để khử đệ quy của sắp xếp nhanh như sau:

Procedure QuickSort(a[1..n]) {
 Var list S, E; Int m:=1
 S(m):=1 ; E(m):= n;
 While m>0  {
   k=S(m); l=E(m)
   m:=m-1;
    if l<l  then {
       i=Part(k,l);
       m=m+1;
       S(m):=i+1
       E(m):=l
    }
 }
 }

Ưu điểm của sắp xếp nhanh không đệ quy nằm ở những cải tiến của giải thuật trên đây. Có thể cải tiến theo những hướng sau: Cất vào ngăn xếp danh sách con ít phần tử hơn trong hai danh sách con và đối với các danh sách con có độ dài đủ nhỏ thì dùng một phương pháp sắp xếp sơ cấp (chẳng hạn sắp xếp chèn).

[sửa] Quick Sort chia ba

Một phương pháp chia khác là chia danh sách thành 3 danh sách con, lần lượt nhỏ hơn, bằng và lớn hơn phần tử chốt.

function quicksort(a)
   Var list less, equal, greater
    if length(a) ≤ 1
        return a
    else
        select a pivot value pivot from a
        for each x in a
            if x < pivot then add x to less
            if x = pivot then add x to equal
            if x > pivot then add x to greater
        return concatenate(quicksort(less), equal, quicksort(greater))
Our "Network":

Project Gutenberg
https://gutenberg.classicistranieri.com

Encyclopaedia Britannica 1911
https://encyclopaediabritannica.classicistranieri.com

Librivox Audiobooks
https://librivox.classicistranieri.com

Linux Distributions
https://old.classicistranieri.com

Magnatune (MP3 Music)
https://magnatune.classicistranieri.com

Static Wikipedia (June 2008)
https://wikipedia.classicistranieri.com

Static Wikipedia (March 2008)
https://wikipedia2007.classicistranieri.com/mar2008/

Static Wikipedia (2007)
https://wikipedia2007.classicistranieri.com

Static Wikipedia (2006)
https://wikipedia2006.classicistranieri.com

Liber Liber
https://liberliber.classicistranieri.com

ZIM Files for Kiwix
https://zim.classicistranieri.com


Other Websites:

Bach - Goldberg Variations
https://www.goldbergvariations.org

Lazarillo de Tormes
https://www.lazarillodetormes.org

Madame Bovary
https://www.madamebovary.org

Il Fu Mattia Pascal
https://www.mattiapascal.it

The Voice in the Desert
https://www.thevoiceinthedesert.org

Confessione d'un amore fascista
https://www.amorefascista.it

Malinverno
https://www.malinverno.org

Debito formativo
https://www.debitoformativo.it

Adina Spire
https://www.adinaspire.com