Skip to content
DSA sorting 8 min read

Built-in Sorting in C++, Java, JavaScript & Python

In real code you should almost always call the standard library sort, not hand-roll one — they are decades-tuned hybrids (introsort, Timsort) that outperform anything you’ll write. The catch is that each language’s API has its own conventions and one famous trap. This page shows the idioms for sorting, sorting with a custom order, and sorting by a key in all four languages.

Sorting ascending — the basics

The default sort puts elements in ascending (natural) order.

#include <algorithm>
#include <vector>

std::vector<int> v = {3, 1, 2};
std::sort(v.begin(), v.end());            // {1, 2, 3}
std::sort(v.begin(), v.end(), std::greater<int>()); // {3, 2, 1} descending

The JavaScript gotcha: Array.prototype.sort() with no comparator converts every element to a string and sorts lexicographically. So [10, 2, 1].sort() returns [1, 10, 2], not [1, 2, 10] — because "10" < "2" as strings. Always pass a comparator for numbers: arr.sort((a, b) => a - b). This is one of the most common JavaScript bugs.

In place vs returning a new array

LanguageIn placeReturns a new sorted copy
C++std::sort(v.begin(), v.end())auto c = v; std::sort(c.begin(), c.end());
JavaArrays.sort(a) / Collections.sort(list)list.stream().sorted().toList()
JavaScriptarr.sort(cmp) (also mutates!)[...arr].sort(cmp) or arr.toSorted(cmp)
Pythonlist.sort()sorted(iterable)

Gotcha: JavaScript’s sort mutates the array and returns it — const b = a.sort() leaves a sorted too. Use arr.toSorted(cmp) (ES2023) or [...arr].sort(cmp) for a non-destructive sort.

Sorting by a key (the most useful skill)

To sort objects by a field — or numbers by a derived value — give the sort a key/comparator. Below: sort words by length, shortest first.

#include <algorithm>
#include <string>
#include <vector>

std::vector<std::string> w = {"bbb", "a", "cc"};
std::sort(w.begin(), w.end(),
          [](const std::string& x, const std::string& y) {
              return x.size() < y.size();   // compare by length
          });
// {"a", "cc", "bbb"}

For beginners: Python’s key= is the cleanest model — you give a function that maps each element to the value to sort by, and Python compares those values. It computes each key once (the “decorate-sort-undecorate” pattern), so it’s also efficient.

Multi-key sorting (ties)

Sort by one field, breaking ties with another — e.g. by age ascending, then name ascending.

struct Person { std::string name; int age; };

std::vector<Person> p = /* ... */;
std::sort(p.begin(), p.end(), [](const Person& a, const Person& b) {
    if (a.age != b.age) return a.age < b.age;
    return a.name < b.name;          // tie-breaker
});

Stability of the built-ins

Stability (equal elements keep their input order) matters for multi-key sorting. As covered on the comparison page:

  • Python sorted/sort — stable (Timsort).
  • JavaScript sort — stable since ES2019.
  • JavaArrays.sort on objects and Collections.sort are stable (Timsort); on primitives it is not stable (dual-pivot quick sort) — but for primitives stability is meaningless since equal ints are indistinguishable.
  • C++ std::sort is not stable; use std::stable_sort when you need it.

Going deeper: Comparators must define a strict weak ordering — consistent and transitive. A broken comparator (e.g. returning true for both cmp(a,b) and cmp(b,a)) is undefined behavior in C++ and throws “Comparison method violates its general contract!” in Java. For numbers, a - b works but can overflow for large ints in C++/Java — prefer Integer.compare(a, b) / (a > b) - (a < b) there.

That’s the practical toolkit. Now lock it in with the sorting exercises.

Last updated June 25, 2026
Was this helpful?