---
# System prepended metadata

title: 'Các giải thuật sắp xếp - P2: Insertion'

---

# Các giải thuật sắp xếp - P2: Insertion
**1. Insertion sort**
Insertion sort hoạt động bằng cách iterate qua mỗi phần tử trong mảng, sau đó tìm vị trí phù hợp cho phần tử đó, và "chèn" phần tử đó vào vị trí.
Mã giả:
```
function InsertionSort(array):
    n = length(array)

    for i from 1 to n - 1:
        key = array[i]       // Current element to be compared
        j = i - 1            // Index of the previous element

        // Move elements of array[0..i-1], that are greater than key, to one position ahead
        // of their current position
        while j >= 0 and array[j] > key:
            array[j + 1] = array[j] 
            j = j - 1

        array[j + 1] = key   // Place the key element at its correct position

    return array
```
Độ phức tạp:
Worst time complexity: n^2
Best time complexity: n
Average time complexity: n^2

**2. Binary insertion sort**

Dễ thấy, việc tìm kiếm vị trí phù hợp cho phần tử a[i] có thể được giải quyết bằng cách chặt nhị phân (i.e. tìm ra vị trí của phần tử nhỏ nhất lớn hơn a[i]).

Mã giả:
```
function BinaryInsertionSort(array):
    n = length(array)

    for i from 1 to n - 1:
        key = array[i]              // Current element to be compared
        left = 0                    // Left pointer for binary search
        right = i - 1               // Right pointer for binary search

        // Binary search to find the correct position for key
        while left <= right:
            mid = (left + right) / 2     // Calculate the middle index
            if array[mid] > key:
                right = mid - 1          // Adjust the right pointer
            else:
                left = mid + 1           // Adjust the left pointer
        
        // Shift elements to the right to make space for key
        for j from i down to left + 1:
            array[j] = array[j - 1]

        array[left] = key           // Place the key element at its correct position

    return array
```
Việc sử dụng binary search để tìm vị trí cho key giúp độ phức tạp trong việc tìm vị trí từ O(n) giảm xuống O(logn). Tuy nhiên, tổng quát, độ phức tạp của Binary insertion sort vẫn còn cao, nên không áp dụng được với mảng có kích thước lớn.
Độ phức tạp:
Worst time complexity: n^2
Best time complexity: n
Average time complexity: n^2

**3. Shell sort**

Một cách khác để cải tiến insertion sort đó là giảm khoảng cách giữa các phần tử có giá trị gần nhau nhưng ở vị trí xa nhau. Ý tưởng của shell sort là chọn ra một khoảng cách (gap) g. Sau đó, mảng sẽ được chia lại thành các mảng con, mà các phần tử trong mảng con cách xa nhau g đơn vị ở trên mảng gốc. Insertion sort các mảng con đó, sau đó giảm g và tiếp tục lặp lại như trên

Mã giả:

```
function ShellSort(array):
    n = length(array)
    gap = n / 2   // Initialize the gap size

    // Start with a large gap, then reduce the gap
    while gap > 0:
        // Do a gapped insertion sort for this gap size
        for i from gap to n - 1:
            temp = array[i]
            j = i

            // Shift earlier gap-sorted elements until the correct location for array[i] is found
            while j >= gap and array[j - gap] > temp:
                array[j] = array[j - gap]
                j = j - gap

            // Insert the element at its correct position
            array[j] = temp

        gap = gap / 2  // Reduce the gap size

    return array
```

Độ phức tạp:
Worst time complexity: n^3/2
Best time complexity: nlogn
Average time complexity: n^4/3