Search code examples
javascriptalgorithmdata-partitioning

How to partition array of integers to even and odd?


I want to partition an array (eg [1,2,3,4,5,6,7,8]), first partition should keep even values, second odd values (example result: [2,4,6,8,1,3,5,7]).

I managed to resolve this problem twice with built-in Array.prototype methods. First solution uses map and sort, second only sort.

I would like to make a third solution which uses a sorting algorithm, but I don't know what algorithms are used to partition lists. I'm thinking about bubble sort, but I think it is used in my second solution (array.sort((el1, el2)=>(el1 % 2 - el2 % 2)))... I looked at quicksort, but I don't know where to apply a check if an integer is even or odd...

What is the best (linear scaling with array grow) algorithm to perform such task in-place with keeping order of elements?


Solution

  • If you are insisting on an in-place approach instead of the trivial standard return [arr.filter(predicate), arr.filter(notPredicate)] approach, that can be easily and efficiently achieved using two indices, running from both sides of the array and swapping where necessary:

    function partitionInplace(arr, predicate) {
        var i=0, j=arr.length;
        while (i<j) {
            while (predicate(arr[i]) && ++i<j);
            if (i==j) break;
            while (i<--j && !predicate(arr[j]));
            if (i==j) break;
            [arr[i], arr[j]] = [arr[j], arr[i]];
            i++;
        }
        return i; // the index of the first element not to fulfil the predicate
    }