Thực hành triển khai các thuật toán sắp xếp cơ bản trong Java

Sắp xếp mảng là một tác vụ nền tảng trong khoa học máy tính và phát triển phần mềm. Việc hiểu rõ cách vận hành của các thuật toán sắp xếp giúp lập trình viên tối ưu hiệu năng xử lý dữ liệu và đưa ra lựa chọn phù hợp cho từng ngữ cảnh cụ thể. Dưới đây là cách triển khai chi tiết một số phương pháp sắp xếp phổ biến bằng ngôn ngữ Java, kèm theo mã nguồn đã được cấu trúc lại để nâng cao tính đọc hiểu và khả năng tùy biến.

1. Thuật toán Sắp xếp nổi bọt (Bubble Sort)

Ý tưởng chính của phương pháp này là so sánh từng cặp phần tử liền kề và hoán đổi vị trí nếu chúng đứng sai thứ tự so với mục tiêu. Quá trình lặp lại cho đến khi một lượt duyệt không còn xảy ra bất kỳ hoán đổi nào. Để hỗ trợ linh hoạt cả hai chiều tăng và giảm, tham số điều khiển được chuyển thành kiểu boolean.

public void sortBubble(int[] data, boolean ascending) {
    int size = data.length;
    for (int pass = 0; pass < size - 1; pass++) {
        boolean swapped = false;
        for (int idx = 0; idx < size - 1 - pass; idx++) {
            boolean needSwap = ascending ? (data[idx] > data[idx + 1]) : (data[idx] < data[idx + 1]);
            if (needSwap) {
                int temp = data[idx];
                data[idx] = data[idx + 1];
                data[idx + 1] = temp;
                swapped = true;
            }
        }
        if (!swapped) {
            break; // Tạm dừng sớm khi mảng đã được sắp xếp hoàn chỉnh
        }
    }
}

2. Thuật toán Sắp xếp chọn (Selection Sort)

Thuật toán này phân chia mảng thành hai phân đoạn: phần đã xử lý và phần chưa xử lý. Trong mỗi vòng lặp, chương trình tìm kiếm phần tử có giá trị cực trị (nhỏ nhất hoặc lớn nhất) trong phân đoạn chưa sắp xếp, sau đó đổi chỗ nó với phần tử đầu tiên của phân đoạn đó.

public void sortSelection(int[] dataset, boolean sortUp) {
    int length = dataset.length;
    for (int boundary = 0; boundary < length - 1; boundary++) {
        int targetIdx = boundary;
        for (int probe = boundary + 1; probe < length; probe++) {
            boolean isTarget = sortUp ? (dataset[probe] < dataset[targetIdx]) : (dataset[probe] > dataset[targetIdx]);
            if (isTarget) {
                targetIdx = probe;
            }
        }
        if (targetIdx != boundary) {
            int swapVal = dataset[boundary];
            dataset[boundary] = dataset[targetIdx];
            dataset[targetIdx] = swapVal;
        }
    }
}

3. Thuật toán Sắp xếp chèn (Insertion Sort)

Phương pháp này xây dựng kết quả bằng cách lần lượt lấy các phần tử từ phân đoạn chưa sắp xếp và chèn chúng vào vị trí chính xác trong phân đoạn đã được xử lý. Các phần tử lớn hơn (hoặc nhỏ hơn) giá trị đang xét sẽ được dịch chuyển sang phía sau để tạo không gian chèn.

public void sortInsertion(int[] values, boolean increaseOrder) {
    for (int currentPos = 1; currentPos < values.length; currentPos++) {
        int pivot = values[currentPos];
        int shiftPos = currentPos;
        while (shiftPos > 0) {
            boolean shouldMove = increaseOrder ? (values[shiftPos - 1] > pivot) : (values[shiftPos - 1] < pivot);
            if (!shouldMove) {
                break;
            }
            values[shiftPos] = values[shiftPos - 1];
            shiftPos--;
        }
        values[shiftPos] = pivot;
    }
}

4. Thuật toán Sắp xếp Shell (Shell Sort)

Đây là phiên bản mở rộng của sắp xếp chèn, cho phép trao đổi các phần tử cách xa nhau thay vì chỉ liền kề. Thuật toán bắt đầu với một bước nhảy (gap) lớn, thực hiện sắp xếp chèn trên các nhóm con được tạo bởi bước nhảy đó, sau đó liên tục thu hẹp bước nhảy cho đến khi đạt giá trị 1, lúc này thuật toán hoạt động chính xác như sắp xếp chèn thông thường.

public void sortShell(int[] arr) {
    int n = arr.length;
    for (int step = n / 2; step > 0; step /= 2) {
        for (int i = step; i < n; i++) {
            int temp = arr[i];
            int j = i;
            while (j >= step && arr[j - step] > temp) {
                arr[j] = arr[j - step];
                j -= step;
            }
            arr[j] = temp;
        }
    }
}

5. Các giải pháp nâng cao và thư viện chuẩn

Ngoài các phương pháp cơ bản đã trình bày, Java còn hỗ trợ triển khai nhiều thuật toán hiệu suất cao hơn như Sắp xếp nhanh (Quick Sort), Sắp xếp theo bucket (Bucket Sort) hay Cấu trúc cây tìm kiếm nhị phân (BST). Trong các dự án thực tế, nhà phát triển nên ưu tiên sử dụng hàm có sẵn của thư viện chuẩn để đảm bảo độ ổn định, bảo mật và hiệu năng tối ưu nhờ các tối ưu hóa ở mức thấp:

int[] numbers = {42, 15, 88, 7, 23, 56};
java.util.Arrays.sort(numbers);

Thẻ: Java Sorting Algorithms Bubble Sort Selection Sort Insertion Sort

Đăng vào ngày 23 tháng 5 lúc 01:14