2017-02-09 14 views
1

Я посещаю базовый класс под названием «Алгоритмы». Мы изучаем алгоритмы сортировки; мы получили следующий псевдокод в качестве примера алгоритма сортировки вставки. Однако я думаю, что это неправильно.Алгоритм сортировки: сортировка вставки - псевдокод, указанный в лекциях, кажется неправильным

For i in {2,..,n}: 
    For j in {i,..,2}: 
     If a(j)<a(j-1), swap a(j) and a(j-1) 
     Else, Break 

Вы также можете увидеть его здесь в конспектов, на этом скриншоте: insertion

Я понимаю первую строку - она ​​начинается с 2, потому что первая карта «уже заказал», так как оно пока единственная карта.

Является ли вторая строка ошибкой? Как может быть, что мы используем j от i до 2? Конечно, это не может быть справедливым в будущем. Кроме того, не должен ли разрыв быть менее отступом? Итак, только одна вкладка вместо 2?

Редактировать

Вот "основная идея" алгоритма. Как видите, диапазон индекса j кажется неправильным. insertion2

Edit2 Так вот я пытаюсь написать, что происходит в моем уме, читая этот псевдокод: Предположим, у меня есть список (5,3,8,7,2,4,1,6). Я напишу |, чтобы отделить «руку» от колоды, также напишу 5_, чтобы подчеркнуть, на каком элементе я смотрю. Так вот мы идем:

i = 1, (5|3,8,7,2,4,1,6) 
i = 2, (5,3|8,7,2,4,1,6), now j in {2}, so we only have j = 2, a(j=2)=3 < a(j=1)=5, hence swap 3 with 5 
i = 3, (3,5,8|7,2,4,1,6), j in {2,3}, so j=2 gives a(j=2)=5 !< a(j=1)=3 SO WE BREAK! 
i = 4, (3,5,8,7|2,4,1,6), j in {2,3,4}, so j = 2 gives a(j=2)=5 !< a(j=1)=3, SO WE BREAK 

и, как вы видите, это всегда будет происходить с этого момента, потому что мы начинаем с 2 и потому, что мы нарушаем его! Таким образом, несмотря на множество целых чисел для J увеличивается, мы не можем идти дальше 2, потому что мы просто нарушают условие

+0

Это псевдокод, так что нет никакого способа, чтобы говорить, что направление шага в 'For' цикла ... вы можете увидеть, что код является правильным , если во втором 'For' размер шага равен' -1'. Однако без каких-либо интродукций это довольно неоднозначный псевдокод. После вашего редактирования ясно, что вы хотите сделать шаг назад во втором цикле. – BeyelerStudios

+0

@BeyelerStudios, я думал об отрицательном шаге. Однако это все равно не сработает. Потому что всякий раз, когда вы «добавляете новую карту в руку», вам нужно проверить эту карту с каждой другой карточкой в ​​руке, а не только со второй! –

+0

Кроме того, каждый раз, когда вы вставляете карту, вы теряете время, потому что вам нужно снова проверить все карты, которые вы уже проверили.$ 2 $, безусловно, ошибка –

ответ

3

Если исходить из следующих предположений, код правильный:

  • Массив длина N имеет индексы 1..N
  • Для петель покрыть указанный диапазон независимо от направления; таким образом, for x in {a,...,b} будет проходить через a, a+1, a+2, ..., b-1, b if a <= b, но пройти через a, a-1, a-2, ..., b+1 b if a >= b.
2

Вторая строка не является ошибкой, потому что вы пытаетесь взять i-й элемент (работающий на внешнем контуре) и вставить в раздел перед ним. Затем вам нужно сравнить этот элемент с разделом перед его сортировкой.

это SO пост имеет хорошую визуализацию: Insertion Sort vs. Selection Sort

+0

Извините, я не понимаю, что вы подразумеваете под «петлей выхода» и «раздела перед ней». –

+0

, как следует из названия, вы ** вставляете ** элемент в уже отсортированный список. Вот почему вы всегда начинаете со второго элемента в массиве, потому что первый элемент уже отсортирован. Поэтому я подразумевал под «разделом перед этим», в этом случае это только первый элемент. –

+0

, но начиная с 2 и доходя до i, это не просто огромное повторение действий? Каждый раз, когда вы вставляете новый элемент в список, вы снова проверяете каждый элемент в списке рядом с ним, который вы уже делали до –

 Смежные вопросы

  • Нет связанных вопросов^_^