Сегодня мой профессор дал нам 2 взять домашние вопросы в качестве практики для предстоящей единицы массива в C, и мне интересно, какой именно алгоритм сортировки эти две проблемы похожи и что такое Big O. Теперь я не прихожу сюда, просто ожидая ответов, и я УЖЕ решил их, но я не уверен в своих ответах, поэтому я буду публиковать их каждый вопрос, и если я ошибаюсь, пожалуйста, исправьте меня и объясните мою ошибку в мышлении.
Вопрос 1:
Если мы решили идти через элемент на массив ( в коробке) (папки) по одному. Начиная с первого элемента и сравнивая его со следующим. Тогда, если они совпадают, сравнение заканчивается, однако, если оба они не равны, то он переходит к сравнению следующих двух ЭЛЕМЕНТОВ [2] и [3]. Этот процесс повторяется и останавливается, когда сравниваются последние два элемента, и обратите внимание, что массив IS уже отсортирован по фамилии, и мы ищем то же имя! Пример: [Харпер Стивен, Хокинг Джон, Инглтон Стивен]
Мой верный ответ:
Я верю, что это O (n), потому что он просто перебирает элементы массива, сравнивая массив [0] с массивом [1], а затем массив [2] с массивом [3] ect ect. Этот процесс является линейным и продолжается до тех пор, пока не будут сопоставлены последние два. Определенно не логн, потому что мы не умножаемся и не ныряем на 2.
Заключительный вопрос: предположим, что у нас есть папка с папками, каждая из которых содержит информацию об одном человеке. Если бы мы хотели искать людей с таким же именем, мы могли бы сначала начать с размещения наклейки в первой папке в коробке, а затем пройти через папки после нее упорядоченным образом, пока мы не найдем человека с таким же именем. Если мы найдем папку с тем же именем, мы перемещаем эту папку рядом с папкой с наклейкой. Как только мы найдем ОДИН случай, когда два человека имеют одно и то же имя, мы останавливаемся и ложимся спать, потому что мы ленивы. Если первый поиск не удается, мы просто удаляем наклейку и помещаем ее в следующую папку, а затем продолжаем, как мы это делали ранее. Мы повторяем этот процесс до тех пор, пока наклейка не появится в последней папке в сценарии, где у нас нет двух людей с одинаковым именем.
Этот массив НЕ отсортирован и сравнивает первую папку с папкой с наклейкой [0] со следующими элементами i-й папки [i].
Мой ответ:
Я чувствую, что это не может быть O (n), но, возможно, O (n ^ 2), где это похоже на массив, а затем мы повторяем процесс, где n пропорционально квадрату входа (папок), Я мог ошибаться здесь через>.>
Вы правы по обоим вопросам... но это поможет объяснить вещи немного более строго. Я не знаю, каковы стандарты вашего класса; вам, вероятно, не нужно фактическое доказательство, но показывая более подробные рассуждения, чем "мы не умножаем или не разделяем на два", никогда не болит. Так…
В первом вопросе, очевидно, ничего не происходит здесь, кроме сравнений, так что мы должны рассчитывать.
И в худшем случае очевидно, что вам нужно пройти весь массив.
Итак, в этом случае вам нужно сравнить a[0] == a[1]
, затем a[1] == a[2]
,..., a[N-1] == a[N]
. Для каждого из элементов N-1
есть 1 сравнение. Это шаги N-1
, что, очевидно, O(N)
.
Тот факт, что массив отсортирован, оказывается здесь неактуальным. (Конечно, поскольку они не сортируются по вашему поисковому ключу, то есть они сортируются по имени, но вы сравниваете по имени - это было уже довольно очевидно).
Во втором вопросе здесь происходят две вещи: сравнения, а затем движения.
Для сравнений наихудший случай заключается в том, что вы должны выполнять все N
поисковых запросов, потому что совпадений нет. Как вы говорите, мы начинаем с a[0]
сравнению a[1]
,..., a[N]
; затем a[1]
против a[2]
,..., a[N]
и т.д. Итак, N-1
сравнения, затем N-2
и т.д. до 0
. Таким образом, общее число сравнений представляет собой sum(0…N-1)
, которая равна N*(N-1)/2
, или N^2/2 - N/2
, что равно O(N^2)
.
Для ходов наихудший случай заключается в том, что вы находите совпадение между a[0]
и a[N]
. В этом случае вам нужно поменять a[N]
a[N-1]
, затем a[N-1]
с a[N-2]
и так далее, пока вы не поменяли a[2]
a[1]
. Итак, что N-1
swaps, что O(N)
, который вы можете игнорировать, потому что у вас уже есть O(N^2)
.
В качестве побочного примечания я не уверен в вашем описании, говоришь ли вы о массиве из a[0…N]
или массиве длины N, поэтому a[0…N-1]
, поэтому может быть ошибка по-одному в обоих вышеперечисленных. Но вам должно быть довольно легко доказать, что это не имеет значения.
Сценарий 2, метод поиска двух совпадающих элементов произвольной величины, действительно "квадратичен". Каждый проход, который ищет совпадение одного кандидата со всеми остальными элементами, - O (n). Но вы повторяете это n раз. Значение n капель по мере того, как вы проходите так, чтобы подробное количество сравнений было бы ближе к n+ (n-1) + (n-2) +... 1, которое равно (n+ 1) × (n/2) или ½ (n² +n), но все, о чем мы заботимся, это общая форма кривой, поэтому не беспокойтесь о членах нижнего порядка или коэффициентах. Это O (n²).