Вы пытались сослаться на элемент после конца списка. Я добавил несколько простых print
утверждений в ваш код:
for k in range(n):
print("LOOP TOP", k, first_half, second_half, list_n)
if j >= len(first_half) and i < len(second_half):
print("TRACE", list_n, k, "\t", first_half, i)
list_n[k] = first_half[i]
i += 1
Затем я сократил список ввода до [8,56,112,3,67]
.
Выход:
LOOP TOP 0 [8] [56] [8, 56]
LOOP TOP 1 [8] [56] [8, 56]
LOOP TOP 0 [3] [67] [3, 67]
LOOP TOP 1 [3] [67] [3, 67]
LOOP TOP 0 [112] [3, 67] [112, 3, 67]
LOOP TOP 1 [112] [3, 67] [3, 3, 67]
TRACE [3, 3, 67] 1 [112] 0
LOOP TOP 2 [112] [3, 67] [3, 67, 67]
TRACE [3, 67, 67] 2 [112] 1
За этим следует крушение, которое вы получили. Вы пытаетесь получить first_half[1]
, когда есть только элемент 0.
АНАЛИЗ
У вас есть три последовательных if
оператора для проверки границ списка:
if j >= len(first_half) and i < len(second_half):
if i >= len(first_half) and j < len(second_half):
if i < len(first_half) and j < len(second_half):
Вы включили i
и j
при первой проверке: i
- индекс first_half
. Это изменение исправляет слияние:
if i < len(first_half) and j >= len(second_half):
Предложения
Часть вашей проблемы в том, что ваша логика слияния слишком сложна. У вас есть единственная проверка значения во время основной части цикла: переместите нижнюю часть заголовков списка в объединенный список. Делайте это, пока оба индекса находятся в диапазоне.
Затем, когда один индекс достигнет конца своего списка, выпадет из цикла и добавит остальные элементы другого списка. Используйте метод extend
. Итак ...
while i < len(first_half) and j < len(second_half):
if first_half[i] < second_half[j]:
# move smaller element to list_n;
# increment i or j as needed
k += 1
# One of these will be an empty operation.
list_n.extend(first_half[i:])
list_n.extend(second_half[j:])