Menyortir data adalah operasi yang paling sering dipakai dari header <algorithm>, dan std::sort adalah pilihan default di C++. Dengan satu pemanggilan, elemen pada rentang [first, last) disusun ulang menjadi urutan menaik berdasarkan operator <. Di balik layar std::sort memakai algoritma hibrida (introsort: quicksort, heapsort, dan insertion sort) dengan kompleksitas O(n log n), sehingga sangat cepat untuk ukuran data menengah dan besar. Chapter ini menunjukkan pemakaian dasar pada angka dan string, menyentuh comparator untuk mengubah urutan, serta memperkenalkan std::stable_sort untuk kasus yang menuntut stabilitas.

Pemakaian Dasar std::sort #

Syarat pemakaian std::sort cuma dua: rentang yang sah dan iterator random access — karena algoritma ini perlu melompat jauh ke tengah data, ia tidak bisa dipakai pada std::list (lihat Chapter Kategori Iterator). Program berikut menyortir vector<int> menaik, menurun, lalu menyortir vector<string>:

cpp
#include <algorithm>
#include <functional>
#include <iostream>
#include <string>
#include <vector>

void cetakAngka(const std::vector<int>& v) {
    for (std::size_t i = 0; i < v.size(); ++i) {
        if (i > 0) std::cout << ' ';
        std::cout << v[i];
    }
    std::cout << '\n';
}

void cetakKata(const std::vector<std::string>& v) {
    for (std::size_t i = 0; i < v.size(); ++i) {
        if (i > 0) std::cout << ' ';
        std::cout << v[i];
    }
    std::cout << '\n';
}

int main() {
    std::vector<int> angka = {42, 7, 19, 3, 25, 11};

    // Default std::sort: urutan menaik (ascending)
    std::sort(angka.begin(), angka.end());
    std::cout << "Angka menaik : ";
    cetakAngka(angka);

    // Comparator eksplisit: menurun (pratinjau; detail di Chapter Custom Comparator)
    std::sort(angka.begin(), angka.end(), std::greater<int>{});
    std::cout << "Angka menurun: ";
    cetakAngka(angka);

    // std::sort juga bekerja pada string lewat perbandingan leksikografis
    std::vector<std::string> nama = {"Dewi", "Budi", "Siti", "Andi"};
    std::sort(nama.begin(), nama.end());
    std::cout << "Nama urut    : ";
    cetakKata(nama);
    return 0;
}

Output yang Dihasilkan:

text
Angka menaik : 3 7 11 19 25 42
Angka menurun: 42 25 19 11 7 3
Nama urut    : Andi Budi Dewi Siti

Bedah baris penting:

  1. Baris 26-27 (std::sort(angka.begin(), angka.end())): tanpa argumen tambahan, sort memakai operator<, sehingga hasilnya menaik: 3 7 11 19 25 42.
  2. Baris 30-31 (std::greater<int>{}): argumen ketiga adalah comparator — objek yang dipanggil seperti fungsi untuk membandingkan dua elemen. greater membalik urutan menjadi menurun; pembahasannya tuntas di Chapter Custom Comparator dan Function Objects.
  3. Baris 34-36: std::string dibandingkan secara leksikografis (kamus), sehingga "Andi" muncul sebelum "Dewi" tanpa perlu comparator khusus.

Perhatikan bahwa std::sort menyusun ulang elemen di tempat (in-place): tidak ada vector baru yang dibuat, dan setelahnya urutan lama tidak bisa dikembalikan. Bila urutan asal masih diperlukan, salin dulu atau gunakan algoritma yang menghasilkan salinan.

Pratinjau Comparator #

Comparator adalah fungsi atau objek fungsi comp(a, b) yang mengembalikan true bila a harus berada sebelum b. std::sort memanggilnya sebagai pengganti operator<. Contoh paling umum adalah lambda untuk menyortir struct berdasarkan satu field:

cpp
std::sort(kelas.begin(), kelas.end(),
          [](const Siswa& a, const Siswa& b) { return a.nilai < b.nilai; });

Snippet tanpa klaim output di atas hanya menunjukkan bentuknya; syarat dan jebakan comparator (strict weak ordering) dibahas lengkap pada Chapter Custom Comparator, sehingga di sini cukup diingat: comparator harus konsisten dan tidak menganggap a < a benar.

Pratinjau std::stable_sort #

Ketika urutan elemen yang setara harus dipertahankan sebagaimana data aslinya, kita memakai std::stable_sort. Algoritma ini menjamin elemen dengan kunci sama tetap dalam urutan relatif semula, dengan biaya kompleksitas yang sama O(n log n) meski biasanya mengalokasikan memori tambahan. Program berikut menyortir siswa dari nilai tertinggi; perhatikan bahwa Siti tetap sebelum Rina, dan Budi tetap sebelum Dewi, karena pasangan-pasangan itu nilai-nilainya sama:

cpp
#include <algorithm>
#include <iostream>
#include <string>
#include <vector>

struct Siswa {
    std::string nama;
    int nilai;
};

int main() {
    std::vector<Siswa> kelas = {
        {"Budi", 85}, {"Siti", 90}, {"Dewi", 85}, {"Andi", 78}, {"Rina", 90},
    };

    // stable_sort: elemen dengan kunci sama mempertahankan urutan aslinya
    std::stable_sort(kelas.begin(), kelas.end(),
                     [](const Siswa& a, const Siswa& b) {
                         return a.nilai > b.nilai;   // nilai tertinggi dulu
                     });

    for (const Siswa& s : kelas) {
        std::cout << s.nama << " (" << s.nilai << ")\n";
    }
    return 0;
}

Output yang Dihasilkan:

text
Siti (90)
Rina (90)
Budi (85)
Dewi (85)
Andi (78)

Lambda pada baris comparator mengembalikan a.nilai > b.nilai, artinya nilai yang lebih besar diletakkan lebih dulu. Aturan keputusannya sederhana: pakai std::sort bila kesetaraan tak penting (biasanya begitu), dan std::stable_sort bila urutan asal bermakna — misalnya daftar yang sudah terurut menurut waktu lalu disortir ulang menurut kategori.

Chapter berikutnya membahas sisi pencarian: std::find dan find_if untuk data apa pun, sebelum kita sampai ke pencarian biner yang menuntut data terurut seperti hasil std::sort ini.

Rujukan resmi: std::sort dan std::stable_sort .