Недавно я разместил здесь вопрос о stackoverflow проблемы временной сложности с multimap, и я получил несколько замечательных ответы, которые отсылали меня к использованию куч, которые, как ни странно, я вообще не использовал до сих пор. Я создал новую программу, переписанную с использованием minheap и maxheap. Она отлично работала, поскольку была намного быстрее, чем любая другая программа, которую я применил для решения этой задачи. Единственная проблема заключалась в том, что время от времени он выдавал неправильные ответы. Я вернулся и сделал много отладки. Я понял, что проблема была в организации моей кучи. Он не сортировался и не распределялся, как я думал, с использованием push_heap и pop_heap с операциями сравнения. Кроме того, когда я пытался запустить программу в Visual Studio, я в конечном итоге видел много ошибок утверждений, выбрасываемых туда. Я попытался прочитать больше о кучах и их методах на сайтах cplusplus.com и cppreference.com. Я думаю, что, возможно, я что-то неправильно понимаю и поэтому сталкиваюсь с дальнейшими проблемами.
Первое, что меня смущает, это push_heap. Я понимаю это следующим образом: push_heap имеет два аргумента и по по умолчанию выдвигает наименьшее значение на позицию last-1. Он делает это только в том случае, если первый аргумент меньше второго аргумента, в противном случае он остается прежним. в основном он поддерживает порядок обычной кучи. Третий необязательный аргумент — это оператор сравнения, который можно использовать как Greater(), который затем помещает больший элемент в позицию last-1.
Что не имеет смысла, так это то, что если у меня происходит динамическая вставка или удаление чисел в векторе, у меня возникают проблемы с сохранением этого порядка. Если бы я хотел, чтобы вектор был в порядке возрастания, я бы использовал большую операцию, чтобы продолжать нажимать кучу, чтобы значения росли. Но это сбивает с толку, когда вы впервые смотрите на метод push_heap, потому что он очень похож на некоторые другие функции алгоритма, которые работают в диапазоне чисел, например:
std::unique (myvector.begin(), myvector.end(), myfunction);
чего push_heap не делает. он не выполняет эту операцию сравнения для всех чисел в диапазоне вектора, чего я сначала не понял.
После того, как я обнаружил, что push_heap на самом деле не поддерживает сортировку моего вектора, и мне пришлось сохранить сортировку моего вектора, чтобы использовать двоичный поиск. Я использовал sort_heap, но это замедлило работу программы настолько, что она была недостаточно быстрой.
Кроме того, я обнаружил, что иногда push_heap в странных случаях выдает ошибку недействительной кучи.
как например:
push_heap(v.begin(), v.end(), greater<int>());
с вектором 755, 98, 55, 22
вы увидите после push_heap:
22, 98, 55, 755
но допустим, что у вас было 22, 98, 55, 755
обычно он просто будет двигаться дальше, не выполняя никаких толчков из-за ложного возврата при сравнении. этого следует ожидать.
но иногда я попробую push_heap:
887, 52, 44, 22
и он скажет
'invalid heap'
или если я попытаюсь: 22, 52, 44, 887, вместо того, чтобы просто вернуть false и двигаться дальше, это сломается с
'invalid heap'
это также иногда происходит с pop_heap.
Почему я получаю недопустимую кучу? это потому, что все кучи должны быть в порядке убывания?
РЕДАКТИРОВАТЬ: я нашел это на cplusplus.com, который, я думаю, отвечает на один вопрос:
The element with the highest value is always pointed by first. The order of the other elements depends on the particular implementation, but it is consistent throughout all heap-related functions of this header.
push_heap
и используйтеstd::priority_queue
. приоритетная очередь работает так же, как и куча, но ее проще использовать и понимать. - person Mooing Duck   schedule 25.03.2013std::priority_queue
имеетpop
иtop
для просмотра и удаления наибольшего элемента. Если это не то, что вам нужно, то и вся эта куча вам не нужна, так как они работают на точно одних и тех же концепциях. - person Mooing Duck   schedule 25.03.2013