Phân Tích Đầy Đủ Các Thuật Toán Sắp Xếp Kinh Điển

Cơ Sở Thuật Toán Sắp Xếp

Thuật toán sắp xếp là công cụ cơ bản trong khoa học máy tính, có khả năng tổ chức dữ liệu theo thứ tự tăng dần hoặc giảm dần. Các thuật toán này tuân thủ hai nguyên tắc chính:

  1. Kết quả đầu ra phải là dãy dữ liệu có thứ tự
  2. Kết quả phải là hoán vị của dữ liệu đầu vào

Trải qua hơn 70 năm phát triển, các nhà khoa học đã đề xuất nhiều phương pháp tối ưu. Bài viết này phân tích chi tiết các thuật toán phổ biến cùng mã nguồn minh họa.

Sắp Xếp Nổi Bọt (Bubble Sort)

Giải thuật đơn giản dựa trên nguyên tắc so sánh lặp các cặp phần tử liền kề và đổi chỗ khi cần:

public class SapXepNoiBot {
    public static int[] sapXep(int[] arr) {
        for (int i=1; i< arr.length; i++) {
            boolean coHoanVi = false;
            for (int j=0; j < arr.length-i; j++) {
                if (arr[j] > arr[j+1]) {
                    int temp = arr[j];
                    arr[j] = arr[j+1];
                    arr[j+1] = temp;
                    coHoanVi = true;
                }
            }
            if (!coHoanVi) break;
        }
        return arr;
    }
}

Sắp Xếp Chọn (Selection Sort)

Phương pháp dựa trên việc tìm kiếm phần tử nhỏ nhất trong đoạn chưa sắp xếp:

public class SapXepChon {
    public static int[] sapXep(int[] arr) {
        for (int i=0; i

Sắp Xếp Chèn (Insertion Sort)

Giải thuật xây dựng mảng có thứ tự bằng cách chèn từng phần tử vào vị trí thích hợp:

public class SapXepChen {
    public static int[] sapXep(int[] arr) {
        for (int i=1; i=0 && arr[j]>key) {
                arr[j+1] = arr[j];
                j--;
            }
            arr[j+1] = key;
        }
        return arr;
    }
}

Sắp Xếp Khoảng Cách Giảm Dần (Shell Sort)

Phiên bản cải tiến của Insertion Sort với việc sử dụng khoảng cách giảm dần:

public class SapXepKhoangCach {
    public static int[] sapXep(int[] arr) {
        int n = arr.length;
        for (int gap=n/2; gap>0; gap/=2) {
            for (int i=gap; i= gap && arr[j-gap] > temp) {
                    arr[j] = arr[j-gap];
                    j -= gap;
                }
                arr[j] = temp;
            }
        }
        return arr;
    }
}

Sắp Xếp Trộn (Merge Sort)

Thuật toán chia để trị hoạt động qua hai giai đoạn:

  1. Chia mảng thành các nửa nhỏ và sắp xếp đệ quy
  2. Trộn các nửa đã sắp xếp thành mảng hoàn chỉnh
public class SapXepTron {
    public static int[] sapXep(int[] arr) {
        if (arr.length <= 1) return arr;
        int mid = arr.length / 2;
        return tron(
            sapXep(Arrays.copyOfRange(arr, 0, mid)),
            sapXep(Arrays.copyOfRange(arr, mid, arr.length))
        );
    }

    private static int[] tron(int[] left, int[] right) {
        int[] result = new int[left.length + right.length];
        int i=0, j=0, k=0;
        while (i < left.length && j < right.length) {
            if (left[i] < right[j]) {
                result[k++] = left[i++];
            } else {
                result[k++] = right[j++];
            }
        }
        while (i < left.length) result[k++] = left[i++];
        while (j < right.length) result[k++] = right[j++];
        return result;
    }
}

Sắp Xếp Nhanh (Quick Sort)

Giải thuật chia mảng thành các phần nhỏ hơn dựa trên phần tử trục (pivot):

public class SapXepNhanh {
    public static int[] sapXep(int[] arr, int left, int right) {
        if (left < right) {
            int pivot = timPivot(arr, left, right);
            sapXep(arr, left, pivot-1);
            sapXep(arr, pivot+1, right);
        }
        return arr;
    }

    private static int timPivot(int[] arr, int left, int right) {
        int pivot = left + (int)(Math.random()*(right-left+1));
        int value = arr[pivot];
        swap(arr, pivot, right);
        int index = left;
        for (int i=left; i

Sắp Xếp Vun Đống (Heap Sort)

Giải thuật dựa trên cấu trúc dữ liệu đống nhị phân:

public class SapXepVunDong {
    public static int[] sapXep(int[] arr) {
        int n = arr.length;
        for (int i=n/2-1; i>=0; i--) {
            vunDong(arr, n, i);
        }
        for (int i=n-1; i>0; i--) {
            int temp = arr[0];
            arr[0] = arr[i];
            arr[i] = temp;
            vunDong(arr, i, 0);
        }
        return arr;
    }

    private static void vunDong(int[] arr, int n, int i) {
        int largest = i;
        int left = 2*i + 1;
        int right = 2*i + 2;

        if (left < n && arr[left] > arr[largest]) {
            largest = left;
        }
        if (right < n && arr[right] > arr[largest]) {
            largest = right;
        }
        if (largest != i) {
            int swap = arr[i];
            arr[i] = arr[largest];
            arr[largest] = swap;
            vunDong(arr, n, largest);
        }
    }
}

So Sánh Hiệu Năng

Thuật ToánĐộ Phức Tạp Tốt NhấtĐộ Phức Tạp Trung BìnhĐộ Phức Tạp Tệ NhấtKhông Gian PhụỔn Định
Bubble SortO(n)O(n²)O(n²)O(1)
Selection SortO(n²)O(n²)O(n²)O(1)
Merge SortO(n log n)O(n log n)O(n log n)O(n)
Quick SortO(n log n)O(n log n)O(n²)O(log n)
Heap SortO(n log n)O(n log n)O(n log n)O(1)

Thẻ: Java Sorting Algorithms Time Complexity Data Structures Algorithm Analysis

Đăng vào ngày 20 tháng 7 lúc 08:07