Ответ 1
Если значения в массиве все положительные (или все отрицательные), один из способов избежать переполнения может заключаться в том, чтобы запускать циклы перестановок и использовать знак integer для маркирования индексированных индексов. (В качестве альтернативы, если длина массива меньше 2 ^ (количество бит для одного элемента массива - 1), вместо использования знака, мы могли бы сдвинуть все значения на один бит влево и использовать первый бит для обозначения посещенных индексов.) Этот алгоритм приводит к как меньшим итерациям, так и меньшим изменениям исходных значений массива во время выполнения, чем алгоритм, который вы просите улучшить.
JSFiddle: http://jsfiddle.net/alhambra1/ar6X6/
Код JavaScript:
function rearrange(arr){
var visited = 0,tmp,indexes,zeroTo
function cycle(startIx){
tmp = {start: startIx, value: arr[startIx]}
indexes = {from: arr[startIx], to: startIx}
while (indexes.from != tmp.start){
if (arr[indexes.from] == 0)
zeroTo = indexes.to
if (indexes.to == visited){
visited++
arr[indexes.to] = arr[indexes.from]
} else {
arr[indexes.to] = -arr[indexes.from]
}
indexes.to = indexes.from
if (indexes.from != tmp.start)
indexes.from = arr[indexes.from]
}
if (indexes.to == visited){
visited++
arr[indexes.to] = tmp.value
} else {
arr[indexes.to] = -tmp.value
}
}
while (visited < arr.length - 1){
cycle(visited)
while (arr[visited] < 0 || visited == zeroTo){
arr[visited] = -arr[visited]
visited++
}
}
return arr
}