Hoán đổi xoay vòng (cyclic swap) 3 biến: x←y, y←z, z←x (hoặc ngược). Dùng call by reference (con trỏ/reference) để sửa giá trị gốc.
Logic xoay vòng
// Trước: x=2, y=5, z=7
// Sau xoay: x=7, y=2, z=5 (x←z, y←x, z←y)
void cyclicSwap(int* x, int* y, int* z) {
int temp = *y; // Lưu y
*y = *x; // y ← x
*x = *z; // x ← z
*z = temp; // z ← y cũ
}
Ví dụ hoàn chỉnh C++ (Reference)
#include <iostream>
using namespace std;
void cyclicSwapping(int& x, int& y, int& z) {
int temp = y;
y = x;
x = z;
z = temp;
}
int main() {
int x, y, z;
cout << "Nhập 3 số: ";
cin >> x >> y >> z;
cout << "Trước swap: x=" << x << ", y=" << y << ", z=" << z << '\n';
cyclicSwapping(x, y, z);
cout << "Sau swap: x=" << x << ", y=" << y << ", z=" << z << '\n';
return 0;
}
Kết quả
Nhập 3 số: 2 5 7
Trước swap: x=2, y=5, z=7
Sau swap: x=7, y=2, z=5
Giải thích bước đi
| Bước | temp | x | y | z |
| Ban đầu | - | 2 | 5 | 7 |
| temp = y | 5 | 2 | 5 | 7 |
| y = x | 5 | 2 | 2 | 7 |
| x = z | 5 | 7 | 2 | 7 |
| z = temp | 5 | 7 | 2 | 5 |
Call by Reference vs Call by Value
| Đặc điểm | Call by Value | Call by Reference |
| Cú pháp | func(int x) | func(int& x) hoặc func(int* x) |
| Truyền | Bản sao giá trị | Địa chỉ/alias của biến gốc |
| Sửa đổi gốc | Không | Có |
| Hiệu năng (object lớn) | Chậm (copy) | Nhanh (không copy) |
C++11: std::rotate (Algorithm)
#include <algorithm>
#include <array>
#include <iostream>
int main() {
std::array arr = {2, 5, 7};
// Xoay trái: 2,5,7 -> 5,7,2
std::rotate(arr.begin(), arr.begin() + 1, arr.end());
// Xoay phải: 2,5,7 -> 7,2,5
std::rotate(arr.rbegin(), arr.rbegin() + 1, arr.rend());
for (int x : arr) cout << x << ' '; // 7 2 5
return 0;
}
Mở rộng: Xoay vòng N phần tử
void rotateLeft(int* arr, int n, int k) {
k %= n;
std::reverse(arr, arr + k);
std::reverse(arr + k, arr + n);
std::reverse(arr, arr + n);
}
// Hoặc dùng std::rotate với pointer