c++sortingcomparatorstable-sort

C++. How to sort by module with saving the original order of elements


I'm trying to sort element in vector by module with the condition that the initial order of equal (by module) elements does not change. Logic tells me that the comparator should take less than or equal to save the original order.

std::sort(v.begin(), v.end(), [](int a, int b) {
    return abs(a) <= abs(b);
});

But with and example of 1 -1 1 -1 my compiler return -1 1 -1 1. Unfortunately it saves order with less than sign(I don't understand why).

Decided that std::sort is not stalbe, I tried to use std::stable_sort and with and example of -1 1 1 -1 -1 it reversed elements in order -1 -1 1 1 -1 - Although I expected that the order would not change with a sign less than or equal.

What am I wrong about? Is there a lambda that is guaranteed to preserve the order of the elements?


Solution

  • What am I wrong about?

    Your programs had undefined behaviour, because std::sort and std::stable_sort require a strict weak order, which <= isn't. Importantly when you compare an element to itself, the comparison must return (a value that converts to) false.

    If you want a stable sort, use std::stable_sort with a valid Compare

    std::stable_sort(v.begin(), v.end(), [](int a, int b) {
        return abs(a) < abs(b);
    });