Dua pointer yang saling mendekat
Membalik array dengan menukar dari kedua ujung, dan satu keputusan halus tentang kapan harus berhenti.
Sebaiknya baca lebih dulu: Mengubah isi di tempatnya, Mencari terkecil dan terbesar.
Bertukar dari kedua ujung
Penukarannya sendiri sudah dipelajari pada pelajaran 1.1: butuh wadah ketiga, sebab menimpa langsung menghilangkan salah satu nilai. Yang baru di sini dua pointer yang bergerak berlawanan arah, dan kapan keduanya harus berhenti.
SET kiri = 0 SET kanan = LENGTH(numbers) - 1 WHILE kiri < kanan SET temp = numbers[kiri] SET numbers[kiri] = numbers[kanan] SET numbers[kanan] = temp SET kiri = kiri + 1 SET kanan = kanan - 1 END
IngatBerhenti tepat saat kedua pointer bertemu. Melanjutkan setelah bertemu berarti menukar ulang apa yang sudah ditukar.
Satu karakter yang membalikkan hasil
Berhenti setelah bersilangan
WHILE kiri <= kanan // tukar numbers[kiri] dengan numbers[kanan] SET kiri = kiri + 1 SET kanan = kanan - 1 END
Berhenti saat bertemu
WHILE kiri < kanan // tukar numbers[kiri] dengan numbers[kanan] SET kiri = kiri + 1 SET kanan = kanan - 1 END
Bedanya satu karakter. Pada array berjumlah genap, kolom kiri melanjutkan setelah kedua pointer bersilangan sehingga setiap pasangan ditukar DUA kali, dan arraynya kembali seperti semula. Tidak ada galat, tidak ada peringatan; yang keluar array yang sama sekali tidak berubah, seolah tidak ada satu baris pun yang dijalankan. Pada jumlah ganjil, kolom kiri menukar elemen tengah dengan dirinya sendiri lalu berhenti, jadi hasilnya kebetulan benar.
Kalimat terakhir itu yang paling perlu dipegang. Pada array berjumlah ganjil, kolom kiri memberi jawaban yang benar. Kalau pengujiannya hanya memakai tiga atau lima elemen, bug ini lolos sepenuhnya dan baru muncul pada data sungguhan yang jumlahnya genap.
Melihat penukaran ganda
SET kiri = 0 SET kanan = 3 WHILE kiri <= kanan // tukar numbers[kiri] dengan numbers[kanan] SET kiri = kiri + 1 SET kanan = kanan - 1 END
Kiri di indeks nol, kanan di indeks tiga. Empat elemen.
Cara paling andal memeriksa pola ini bukan menjalankannya di kepala sampai selesai, melainkan menghitung jumlah penukarannya. Array berisi N elemen membutuhkan tepat N dibagi dua penukaran, dibulatkan ke bawah. Empat elemen dua penukaran, lima elemen juga dua, enam elemen tiga. Kalau jumlah penukarannya lebih dari itu, ada pasangan yang ditukar dua kali.
Array yang tidak perlu ditukar
- Array kosong: kanan dimulai dari negatif satu, dan kondisi 0 < -1 sudah salah. Nol penukaran, arraynya keluar kosong.
- Array berisi satu elemen: kiri dan kanan sama sama nol, dan 0 < 0 salah. Nol penukaran, dan itu benar sebab satu elemen yang dibalik tetap dirinya sendiri.
- Array berisi dua elemen: satu penukaran, lalu kiri menjadi satu dan kanan menjadi nol. Kondisinya salah, berhenti.
Perhatikan butir pertama. Kanan bernilai negatif satu pada array kosong, dan itu indeks yang tidak ada. Ia tidak pernah menjadi masalah karena kondisinya sudah salah sebelum satu pun pembacaan terjadi, tepat seperti loop berhitung pada pelajaran 3.1. Nilai yang tidak sah aman selama ia tidak pernah dipakai.
Periksa pemahaman
Berapa penukaran yang dibutuhkan array berisi enam elemen, dan berapa untuk tujuh?
Ringkasan
- Dua pointer bergerak berlawanan arah, satu dari awal dan satu dari indeks terakhir.
- Berhenti tepat saat keduanya bertemu, memakai lebih kecil dari, bukan lebih kecil atau sama dengan.
- Melanjutkan setelah bertemu menukar ulang pasangan yang sudah ditukar, dan arraynya kembali seperti semula tanpa satu pun galat.
- Kesalahan ini tidak muncul pada array berjumlah ganjil, jadi uji dengan jumlah genap.
- Jumlah penukaran wajib sama dengan panjang dibagi dua dibulatkan ke bawah. Pakai itu untuk memeriksanya.
- Penukarannya tetap butuh wadah ketiga, sama seperti pelajaran pertama.