Интересно, поможет ли это:
Если мы добавим некоторые записи в вашу функцию, мы можем сгенерировать такой вывод:
mergeSort ([3,4,2,1])
left:
mergeSort ([3,4])
left:
mergeSort ([3])
==> [3]
right:
mergeSort ([4])
==> [4]
merge ([3], [4])
==> [3,4]
right:
mergeSort ([2,1])
left:
mergeSort ([2])
==> [2]
right:
mergeSort ([1])
==> [1]
merge ([2], [1])
==> [1,2]
merge ([3,4], [1,2])
==> [1,2,3,4]
result: [1,2,3,4]
Рекурсивный вызов ничего не завершает. Он просто возвращает значение тому, кто его вызвал. В root это начальный вызов mergeSort
. Для внутренних вызовов это вызов для сортировки левой половины или сортировки правой половины.
Таким образом, при каждом вызове mergeSort
, когда мы не достигаем нашего базового случая, мы разбиваем Оставшийся массив пополам (-i sh) и рекурсивно вызвать его для сортировки левой половины, затем рекурсивно вызвать его для сортировки правой половины, а затем объединить две половины обратно, что просто, поскольку теперь они отсортированы.
Это одна из тех вещей, которые вы можете обнаружить, играя в карты. Если вы хотите отсортировать всю колоду со случайным перемешиванием, один из лучших способов - разделить ее пополам, отсортировать каждую половину и объединить их, поместив перед собой две отсортированные стопки, постоянно вытягивая наименьшее значение из тех, которые отображаются в добавить в свою основную кучу. Но для сортировки одной из этих полукодок лучше всего разделить ее пополам, отсортировать ... И, таким образом, рекурсию. Я лично сделаю это на несколько уровней. Когда я получаю три или четыре карточки, я сортирую их по проверке.
Этот фрагмент показывает, как я добавил запись:
const log = (indent, message) =>
console.log (Array(indent * 2).fill(' ').join('') + message)
var mergeSort = function (nums, indent = 0) {
log (indent, `mergeSort ([${nums}])`)
if (nums.length <= 1) {
log (indent, `==> [${nums}]`)
return nums;
}
let mid = Math.floor(nums.length / 2);
let left = nums.slice(0, mid);
let right = nums.slice(mid);
log (indent + 1, 'left:')
left = mergeSort(left, indent + 2);
log (indent + 1, 'right:')
right = mergeSort(right, indent + 2);
let block = [];
let l = 0;
let r = 0;
log (indent + 1, `merge ([${left}], [${right}])`)
while (l < left.length && r < right.length) {
if (left[l] < right[r]) {
block.push(left[l]);
l++;
} else {
block.push(right[r]);
r++;
}
}
if (l < left.length) {
block = block.concat(left.slice(l));
} else if (r < right.length) {
block = block.concat(right.slice(r));
}
log (indent, `==> [${block}]`)
return block;
};
console .log ('', `result: [${mergeSort([3, 4, 2, 1])}]`)