"Я хочу изменить значения от 7 до 4, от 16 до 4 и от 4 до 3,5. Но я не уверен, где они будут в куче. Индексы значений элементов, которые должны быть уменьшены, будутдано относительно исходного вектора v. ... Пожалуйста, дайте мне знать, если мне придется переосмыслить некоторые из моей логики. "
Вместо того, чтобы манипулировать значениями внутри кучи, я бы предложил сохранить значения, которыенужно изменить внутри вектора (возможно, сам по себе).Куча может быть основана на элементах, которые являются структурой (или классом), которая содержит index в соответствующей позиции в векторе со значениями, а не содержит само (изменяющееся) значение.
Структура (или класс) будет реализовывать функцию operator <, которая сравнивает значения, извлеченные из двух векторов, для соответствующих значений индекса.Таким образом, вместо сохранения значения сравнения в элементах кучи и сравнения a <b, вы должны хранить позиции индекса i и j и т. Д. И сравнивать v [i] <v [j] с целью упорядочения кучи. </p>
Таким образом, позиции числовых значений, которые вам нужно обновить, никогда не изменятся с их исходных позиций.Информация о местоположении никогда не устареет (как я понимаю из вашего описания).
Конечно, когда вы вносите изменения в эти сохраненные значения в векторе, это может легко аннулировать любой порядок, который мог существовать вкуча сама.Насколько я понимаю ваше описание, в любом случае это обязательно было правдой.Поэтому, в зависимости от того, как вы меняете значения, вам может потребоваться выполнить новый make_heap, чтобы восстановить правильное упорядочение кучи.(Это не ясно, поскольку это зависит от того, нарушают ли ваши предполагаемые изменения допущения в куче, но было бы безопасно предположить, если нет сильных гарантий в противном случае.)
Я думаю, все остальное довольно просто.,Вы все еще можете работать с кучей, как вы и предполагали ранее.Для простоты вы могли бы даже дать структуре (или классу) функцию поиска, которая будет возвращать текущее значение в его соответствующей позиции в векторе, если вам нужно это (а не индекс), когда вы выводите минимальные значения.
ps Вот вариант той же идеи.
В приведенной выше исходной версии, скорее всего, потребуется также сохранить указатель на местоположение вектора, в котором содержится вектор значений, возможно, в качестве общей статики.указатель этой структуры (или класса), чтобы все члены могли разыменовать указатель на этот вектор в сочетании со значениями индекса для поиска конкретного члена, связанного с этим элементом.
Если вы предпочитаете, вместо сохраненияэтот общий указатель вектора и индекс в каждом члене, каждый экземпляр структуры (или класса) может более просто хранить указатель (или итератор) непосредственно в местоположении соответствующего значения.Если значения являются целыми числами, значением члена структуры элемента кучи может быть указатель int.Хотя каждый указатель может быть больше, чем значение индекса, у него есть то преимущество, что он исключает любые предположения о структуре данных, которая содержит сравниваемые значения, и еще проще / быстрее разыскивает сопоставление с поиском по индексу в векторе.(Оба имеют постоянное время.)
Одно предупреждение: в этом альтернативном подходе значения указателя будут недействительными, если вы заставите изменения позиций хранения вектора, например, путем добавления новых значений и расширения их впуть, который заставляет его перераспределить его пространство.Я предполагаю, что вам нужно только изменить значения, а не расширять количество значений после того, как вы начали использовать кучу.Но если вам нужно было это сделать, это было бы одной из причин отдавать предпочтение значениям индекса, поскольку они остаются действительными после расширения вектора (в отличие от указателей).
p.p.s. Эта техника также полезна, когда объекты, которые вы хотите сравнить в куче, большие. Вместо того, чтобы куча выполняла много операций копирования на больших объектах, поскольку она переупорядочивает позиции элементов кучи, сохраняя только указатели (или значения индекса), копирование намного эффективнее. Фактически это позволяет использовать кучу объектов, которые вы вообще не хотите копировать.
Вот краткое представление об одной версии функции сравнения (теперь добавлен некоторый контекст класса).
class YourHeapElementClassName
{
public:
// constructor
explicit YourHeapElementClassName(theTypeOfYourComparableValueOrObject & val)
: m_valPointer(&val)
{
}
bool operator<(const YourHeapElementClassName & other) const
{
return *m_valPointer < *(other.m_valPointer);
}
...
private:
theTypeOfYourComparableValueOrObject * m_valPointer;
}; // YourHeapElementClassName
// and later instead of making a heap of int or double,
// you make a heap of YourHeapElementClassName objects
// that you initialize so each points to a value in v
// by using the constructor above with each v member.
// If you (probably) don't need to change the v values
// through these heap objects, the member value could be
// a pointer to a const value and the constructor could
// have a const reference argument for the original value.
Если вам нужно было сделать это с различными типами значений или объектов, подход указателя может быть реализован с помощью шаблона, который обобщает тип значения или объекта и содержит указатель на этот общий тип.