Sắp xếp Shell Sort

Shell sort là một thuật toán sắp xếp hiệu quả cao và dựa trên thuật toán sắp xếp chèn. Thuật toán này tránh các dịch chuyển lớn như trong trường hợp sắp xếp chèn, nếu giá trị nhỏ hơn nằm ở bên phải và phải được chuyển sang bên trái.

Đầu tiên, 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ảng cách xa nhau, sau đó sắp xếp các phần tử có khoảng cách hẹp hơn. Khoảng cách này còn được gọi là khoảng (interval) – là số vị trí từ phần tử này tới phần tử khác. Khoảng này được tính dựa vào công thức Knuth như sau:

h = h * 3 + 1

Trong đó:

   h là khoảng (interval) với giá trị ban đâu là 1

Giải thuật này khá hiệu quả với các tập dữ liệu có kích cỡ trung bình khi mà độ phức tạp trường hợp xấu nhất và trường hợp trung bình là O(n), với n là số phần tử.

Cách Shell Sort làm việc

Để dễ tìm hiểu hơn, dưới đây mình cung cấp các hình minh họa cho cách Shell Sort làm việc. Chúng ta sử dụng một mảng gồm các giá trị như dưới đây. Giả sử ban đầu giá trị Khoảng (interval) là 4. Ví dụ, với phần tử 35 thì với khoảng là 4 thì phần tử còn lại sẽ là 14. Do đó ta sẽ có các cặp giá trị {35, 14}, {33, 19}, {42, 27}, và {10, 44}.

So sánh các giá trị này với nhau trong các danh sách con và tráo đổi chúng (nếu cần) trong mảng ban đầu. Sau bước này, mảng mới sẽ trống như sau:

Sau đó, lấy giá trị Khoảng (interval) là 2 và với khoảng cách này sẽ cho hai danh sách con: {14, 27, 35, 42}, {19, 10, 33, 44}.

Tiếp tục so sánh và tráo đổi các giá trị (nếu cần) trong mảng ban đầu. Sau bước này, mảng sẽ trông như sau:

Cuối cùng, chúng ta sắp xếp phần mảng còn lại này với Khoảng (interval) bằng 1. Shell Sort sử dụng giải thuật sắp xếp chèn để sắp xếp mảng. Dưới đây là hình minh họa cho từng bước.

Như trên các hình trên, bạn thấy rằng chúng ta chỉ cần 4 lần tráo đổi để sắp xếp phần mảng còn lại này.

Giải thuật cho Shell Sort

Bây giờ chúng ta sẽ theo dõi giải thuật cho Shell Sort:

Bước 1: Khởi tạo giá trị h

Bước 2: Chia list thành các sublist nhỏ hơn tương ứng với h

Bước 3: Sắp xếp các sublist này bởi sử dụng sắp xếp chèn (Insertion Sort)

Bước 4: Lặp lại cho tới khi list đã được sắp xếp

Giải thuật mẫu cho Shell Sort

Từ các bước trên chúng ta có thể thiết kế một giải thuật mẫu cho Shell Sort như sau:

procedure shellSort()

   A : array of items            

   /* calculate interval*/

   while interval < A.length /3 do:

      interval = interval * 3 + 1                

   end while

   while interval > 0 do:

      for outer = interval; outer < A.length; outer ++ do:

      /* select value to be inserted */

      valueToInsert = A[outer]

      inner = outer;

         /*shift element towards right*/

         while inner > interval -1 && A[inner - interval] >= valueToInsert do:

            A[inner] = A[inner - interval]

            inner = inner - interval

         end while

      /* insert the number at hole position */

      A[inner] = valueToInsert

      end for

   /* calculate interval*/

   interval = (interval -1) /3;  

   end while

end procedure

- Hiếu Kiều -