Triển Khai Thủ Công Hàm Trao Đổi Phần Tử Trong Ngôn Ngữ C++

Tổng Quan Vấn Đề

Khi phát triển các giải thuật xử lý dữ liệu mà không sử dụng thư viện chuẩn đầy đủ, việc thao tác trực tiếp trên vùng nhớ trở nên cần thiết. Một tình huống phổ biến là thực hiện hoán đổi giá trị giữa hai biến để hỗ trợ các thuật toán sắp xếp như sắp xếp chọn hoặc sắp xếp bong bóng. Dưới đây là phân tích các phương pháp cơ bản để thực hiện chức năng này trong C++.

Cách Tiếp Cận Thông Qua Tham Chiếu

Phương pháp hiệu quả và an toàn nhất khi làm việc với kiểu dữ liệu cơ bản là truyền tham chiếu. Cách này cho phép hàm truy cập trực tiếp vào địa chỉ bộ nhớ của biến gốc mà không sao chép giá trị, đồng thời tránh được sự mơ hồ của con trỏ thủ công.

void TraoDoiRef(int& bienA, int& bienB) {
    int tamNhan = bienA;
    bienA = bienB;
    bienB = tamNhan;
}

Cách Tiếp Cận Thông Qua Con Trỏ Hằng

Nếu muốn kiểm soát chặt chẽ hơn về mức độ truy cập, có thể sử dụng con trỏ hướng tới hằng số hoặc ngược lại, đảm bảo rằng địa chỉ chứa biến không bị thay đổi trong quá trình thực thi hàm, nhưng giá trị tại địa chỉ đó có thể được viết đè lên.

void TraoDoiPtr(int* const diaChiA, int* const diaChiB) {
    int giaTriTam = *diaChiA;
    *diaChiA = *diaChiB;
    *diaChiB = giaTriTam;
}

Hiệu Suất Với Hàm Trao Đổi Kết Hợp

Một số lập trình viên kết hợp cả tham chiếu và con trỏ bằng cách lấy địa chỉ từ biến tham chiếu rồi mới giải chiếu. Tuy nhiên, kỹ thuật này thường dư thừa so với phương pháp tham chiếu thuần túy vì trình biên dịch tối ưu hóa tốt trường hợp tham chiếu. Dù vậy, về mặt ngữ nghĩa, nó vẫn hoạt động đúng.

void TraoDoiHopper(int& refA, int& refB) {
    int* pA = &refA;
    int* pB = &refB;
    int temp = *pA;
    *pA = *pB;
    *pB = temp;
}

Ví Dụ Tích Hợp Vào Giải Thuật Sắp Xếp

Dưới đây là ví dụ hoàn chỉnh mô phỏng thuật toán sắp xếp bong bóng sử dụng hàm trao đổi tùy chỉnh đã xây dựng ở trên. Mã nguồn bao gồm việc khởi tạo mảng cố định và hiển thị kết quả ra màn hình console.

#include <iostream>
using namespace std;

// Định nghĩa hàm hoán đổi qua tham chiếu
inline void SwapElements(int& left, int& right) {
    int buffer = left;
    left = right;
    right = buffer;
}

// Thực thi sắp xếp bong bóng
void PerformBubbleSort(const int* sourceData, size_t count, int* targetData) {
    // Sao chép dữ liệu để bảo toàn mảng gốc
    for (size_t i = 0; i < count; ++i) {
        targetData[i] = sourceData[i];
    }

    bool isSorted = false;
    for (size_t i = 0; i < count - 1 && !isSorted; ++i) {
        isSorted = true;
        for (size_t j = 0; j < count - 1 - i; ++j) {
            if (targetData[j] > targetData[j + 1]) {
                SwapElements(targetData[j], targetData[j + 1]);
                isSorted = false;
            }
        }
    }
}

int main() {
    constexpr size_t ArraySize = 10;
    const int inputData[ArraySize] = { 5, 8, 1, 9, 3, 7, 2, 6, 4, 0 };
    int outputBuffer[ArraySize];

    PerformBubbleSort(inputData, ArraySize, outputBuffer);

    // Hiển thị kết quả
    for (size_t k = 0; k < ArraySize; ++k) {
        cout << outputBuffer[k] << " ";
    }
    cout << endl;

    return 0;
}

Kết quả thực thi sẽ trả về dãy số đã được sắp xếp theo thứ tự tăng dần:

0 1 2 3 4 5 6 7 8 9

Thẻ: C++ Algorithms bubble-sort memory-handling Data-Structures

Đăng vào ngày 30 tháng 6 lúc 07:34