RemoveAt
занимает O (n) время. Потому что он должен сдвигать элементы влево, начиная с индекса i
до n
(Items.Count
). Аналогично для IndexOf
.
Асимптотическая оценка вашего кода:
public void RemoveItem(string name)
{
foreach (var item in Items) //n times
{
if (item.Name == name)
{
Items.RemoveAt(Items.IndexOf(position)); // O(n) + O(n) => O(n)
}
}
// => O(n * n)
}
работает за O (n ^ 2) раз.
Как насчет этого кода?
for (int i = Items.Count - 1; i >= 0; i--) // n times
{
if (Items[i].Name == name)
{
Items.RemoveAt(i); //O(n)
}
}
Так что это также работает в O (n ^ 2)
но этот код:
Items.RemoveAll(i => item.Name == name);
работает за O (n) время. Вы должны увидеть реализацию этого метода для доказательства.
RemoveAll
выполняет итерацию ОДИН РАЗ через элементы списка, и, если критерии соблюдены, она также начнет смещаться во время итерации. Это смещение на каждом шаге является одним назначением, т. Е. O (1). Поэтому весь метод выполняется за время O (n), что намного быстрее, чем ваша реализация.
UPDATE :
Теперь вопрос содержит break;
после строки удаления.
В этом коде поиск элементов будет остановлен после обнаружения, и начнется удаление, что будет стоить O (n) + O (n) => O (n).
Так что не будет никакой асимптотической разницы между рассматриваемым кодом и RemoveAll
.
Так что это не так быстро и НЕ МОЖЕТ БЫТЬ, но все же RemoveAll
более чистый код ИМХО.