简体   繁体   中英

How to sort an array so that the largest value gets in the middle?

Assume I have a simple array:

[1, 20, 15, 37, 46, 9]

I need to make it look like this:

[1, 9, 15, 46, 37, 20]

So the idea is to put the largest value or pair of the largest two values in the middle of the array then put decreasing numbers to the right and to the left of it like a pyramid.

I have a couple of ideas but they don't seem elegant enough. Please advise.

Try this:

var arr = [1, 20, 15, 37, 46, 9];
arr.sort(function (a, b) {
    return a - b;
});
var arr1 = arr.slice(0, arr.length / 2);
var arr2 = arr.slice(arr.length / 2, arr.length);
arr2.sort(function (a, b) {
    return b - a;
});
arr = arr1.concat(arr2);
console.log(arr);

This method is resumed to two steps:

[1, 20, 15, 37, 46, 9]    // step 1: sort the entire array
[1, 9, 15, 20, 37, 46]    // step 2: sort the second half of the array
[1, 9, 15, 46, 37, 20]
var arr = [1,20,15,37,46,9];
arr.sort(function(a,b){
 return a-b;
});
var right = arr.slice(arr.length/2,arr.length).reverse();
var left = arr.slice(0,arr.length/2);
arr = left.concat(right);
console.log(arr);

This can be optimized, but it works.

function pyramid (arr) {
    var newArr = [];

    // sort numerically
    arr.sort(function (a, b) {
        return a - b;
    });

    // put the biggest in new array
    newArr.push(arr.pop());

    // keep grabbing the biggest remaining item and alternate
    // between pushing and unshifting onto the new array
    while (arr.length) {
        newArr[arr.length % 2 === 0 ? 'push' : 'unshift'](arr.pop());
    }

    return newArr;
}

pyramid([1, 20, 15, 37, 46, 9] returns [1, 15, 37, 46, 20, 9]

I can't give you a javascript example, but I would first put each array element in order, then enumerate (give an index), and then add them in even/odd order from front and back.

[1, 20, 15, 37, 46, 9]

becomes

[1, 9, 15, 20, 37, 46]

then print odd indices up to half the array size, and then print even indices from the end back down to halfway.

edit: python for fun:

tt = sorted([1, 20, 15, 37, 46, 9])
print tt[0:len(tt)/2] + list(reversed(tt[len(tt)/2:len(tt)]))

Here is another short chained approach:

[1, 20, 15, 37, 46, 9].sort(function(a, b) {
    return a - b;
}).map(function(v, i, a) {
    var p = ~~(a.length / 2);
    return i >= p ? a[a.length - i + p - 1] : v;
});

// [1, 9, 15, 46, 37, 20]

Seems to work fine with any number of elements in the array.

The technique of sorting the array, halving it, then splicing them together doesn't work as well when you have more elements. One side is "bigger" than the other.

let arr = [361, 324, 289, 256, 225, 196, 169, 144, 121, 100, 81, 64, 49, 36, 25, 16, 9, 4, 1, 0];
arr = arr.slice(arr.length/2).reverse().concat(arr.slice(0,arr.length/2));
// [0, 1, 4, 9, 16, 25, 36, 49, 64, 81, 361, 324, 289, 256, 225, 196, 169, 144, 121, 100]

Interleaving the odd and even indexes looks better, and only takes slightly longer

arr = arr.filter((v, i)=>i % 2 === 0).reverse().concat(arr.filter((v, i)=>i % 2 === 1));
// [1, 9, 25, 49, 81, 121, 169, 225, 289, 361, 324, 256, 196, 144, 100, 64, 36, 16, 4, 0]

Much simpler algorithm

First - order the array in a descending order and define a new empty array.

Second - iterate through the sorted array and insert its items in the following way - if even push to the empty array else unshift the item.

Example

let randoms = [7 ,53 ,21, 43 ,45 ,8, 12, 9, 3, 22, 21]; //some random unsorted array

randoms.sort((a,b) => b - a);   // sorting the array
let sortedFromMiddle = []; //the new empty array

randoms.forEach(( num, index ) => { 
    index % 2 === 0 ? sortedFromMiddle.push(num) : sortedFromMiddle.unshift(num);
  });

console.log(sortedFromMiddle); // will log the array 

The return from a splice is an array of items that is removed from the original-

function pyramid(arr){
    var  mid= Math.floor(arr.length/2);
    var a2= arr.sort(function(a,b){return a-b}).splice(mid);
    return arr.concat(a2.reverse());
}

var a1= [1, 20, 15, 37, 46, 9];
pyramid(a1)

/* returned value: (Array) 1,9,15,46,37,20 */

var data = [1, 20, 15, 37, 46, 9];
arr = data.sort(function(a, b){return a - b});
console.log(arr);

This will return you [1, 9, 15, 20, 37, 46]

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM