我有一个Max堆,但是我想编辑代码以便可以创建Min堆。为了清楚起见,我希望能够轻松地从Max切换到Min堆,因为我将它用于两个独立的优先级队列,一个基于Min,另一个基于Max。
这是我的Heap.cpp
// *********************************************************
// Implementation file Heap.cpp for the ADT heap.
// *********************************************************
#include "Heap.h" // header file for heap
heapClass::heapClass() : Size(0)
{
} // end default constructor
bool heapClass::HeapIsEmpty() const
{
return bool(Size == 0);
} // end HeapIsEmpty
void heapClass::HeapInsert(const heapItemType& NewItem,
bool& Success)
// Method: Inserts the new item after the last item in the
// heap and trickles it up to its proper position. The
// heap is full when it contains MAX_HEAP items.
{
Success = bool(Size < MAX_HEAP);
if (Success)
{ // place the new item at the end of the heap
Items[Size] = NewItem;
// trickle new item up to its proper position
int Place = Size;
int Parent = (Place - 1)/2;
while ( (Parent >= 0) &&
(Items[Place].Key() > Items[Parent].Key()) )
{ // swap Items[Place] and Items[Parent]
heapItemType Temp = Items[Parent];
Items[Parent] = Items[Place];
Items[Place] = Temp;
Place = Parent;
Parent = (Place -1 )/2;
} // end while
++Size;
} // end if
} // end HeapInsert
void heapClass::HeapDelete(heapItemType& RootItem,
bool& Success)
// Method: Swaps the last item in the heap with the root
// and trickles it down to its proper position.
{
Success = bool(!HeapIsEmpty());
if (Success)
{ RootItem = Items[0];
Items[0] = Items[--Size];
RebuildHeap(0);
} // end if
} // end HeapDelete
void heapClass::RebuildHeap(int Root)
{
// if the root is not a leaf and the root's search key
// is less than the larger of the search keys in the
// root's children
int Child = 2 * Root + 1; // index of root's left
// child, if any
if ( Child < Size )
{ // root is not a leaf, so it has a left child at Child
int RightChild = Child + 1; // index of right child,
// if any
// if root has a right child, find larger child
if ( (RightChild < Size) &&
(Items[RightChild].Key() > Items[Child].Key()) )
Child = RightChild; // index of larger child
// if the root's value is smaller than the
// value in the larger child, swap values
if ( Items[Root].Key() < Items[Child].Key() )
{ heapItemType Temp = Items[Root];
Items[Root] = Items[Child];
Items[Child] = Temp;
// transform the new subtree into a heap
RebuildHeap(Child);
} // end if
} // end if
// if root is a leaf, do nothing
} // end RebuildHeap
Heap.h
// *********************************************************
// Header file Heap.h for the ADT heap.
// *********************************************************
#include "Data.h" // definition of itemClass
#include "PrecondViolatedExcep.h"
#pragma once
const int MAX_HEAP = 20;
typedef itemClass keyType;
typedef itemClass heapItemType;
class heapClass
{
public:
heapClass(); // default constructor
// copy constructor and destructor are
// supplied by the compiler
// heap operations:
virtual bool HeapIsEmpty() const;
// Determines whether a heap is empty.
// Precondition: None.
// Postcondition: Returns true if the heap is empty;
// otherwise returns false.
virtual void HeapInsert(const heapItemType& NewItem,
bool& Success);
// Inserts an item into a heap.
// Precondition: NewItem is the item to be inserted.
// Postcondition: If the heap was not full, NewItem is
// in its proper position and Success is true;
// otherwise Success is false.
virtual void HeapDelete(heapItemType& RootItem,
bool& Success);
// Retrieves and deletes the item in the root of a heap.
// This item has the largest search key in the heap.
// Precondition: None.
// Postcondition: If the heap was not empty, RootItem
// is the retrieved item, the item is deleted from the
// heap, and Success is true. However, if the heap was
// empty, removal is impossible and Success is false.
protected:
void RebuildHeap(int Root);
// Converts the semiheap rooted at index Root
// into a heap.
private:
heapItemType Items[MAX_HEAP]; // array of heap items
int Size; // number of heap items
}; // end class
// End of header file.
包含itemClass的片段
#include <stdio.h>
#include "Data.h"
/* Put in definitions of methods declared in Data.h
- modify as you wish. */
/* ==================================================
Default constructor
================================================== */
itemClass::itemClass() : trackRequest(-100),
serialNum(-1)
{
}
/* ==================================================
Constructor
================================================== */
itemClass::itemClass(int trkR, int srlNum, bool dir)
: trackRequest(trkR),
serialNum (srlNum),direction(dir)
{
}
/* ==================================================
Key
================================================== */
/* This method returns the search key.
Here we assume the key is the item itself. */
itemClass itemClass::Key() const
{
return *this ;
}
/* ==================================================
Equality Test
================================================== */
bool itemClass::operator== (const itemClass& Rhs) const
{
return (trackRequest == Rhs.trackRequest)
&& (serialNum == Rhs.serialNum) && (direction== Rhs.direction);
}
/* ==================================================
non-Equality Test
================================================== */
bool itemClass::operator!= (const itemClass& Rhs) const
{
return !(*this==Rhs) ;
}
/* ==================================================
Less-Than Test
================================================== */
bool itemClass::operator< (const itemClass& Rhs) const
{
return(trackRequest < Rhs.trackRequest) && (direction <=Rhs.direction);
//return true;
}
/* ==================================================
Less-Than-Or-Equal Test
================================================== */
bool itemClass::operator<= (const itemClass& Rhs) const
{
return (*this<Rhs) || (*this==Rhs) ;
}
/* ==================================================
Greater-Than Test
================================================== */
bool itemClass::operator> (const itemClass& Rhs) const
{
return (!(*this<Rhs) && !(*this==Rhs)) ;
/* OR return (Rhs<*this); */
}
/* ==================================================
Greater-Than-Or-Equal Test
================================================== */
bool itemClass::operator>= (const itemClass& Rhs) const
{
return ( !(*this<Rhs) ) ;
}
答案 0 :(得分:1)
你想要做的是让你的heapClass
构造函数采用比较函数,你可以在课堂内部保存。然后让您的heapClass
函数使用函子进行比较。您可以将其默认为operator<
itemClass
。但你也可以通过operator>
传递顺序。
例如,请查看Compare functor
如何传递给std::set
以定义其排序http://en.cppreference.com/w/cpp/container/set
答案 1 :(得分:1)
有一些简单的方法。一种方法是将函数参数添加到heapClass
进行比较。
template <typename Compare = std::greater<itemClass>>
class heapClass {
private:
Compare cmp;
public:
heapClass(Compare cmp = Compare()) : cmp(cmp);
void HeapInsert(const heapItemType& NewItem,
bool& Success)
// Method: Inserts the new item after the last item in the
// heap and trickles it up to its proper position. The
// heap is full when it contains MAX_HEAP items.
{
Success = bool(Size < MAX_HEAP);
if (Success)
{ // place the new item at the end of the heap
Items[Size] = NewItem;
// trickle new item up to its proper position
int Place = Size;
int Parent = (Place - 1)/2;
while ( (Parent >= 0) &&
(cmp(Items[Place].Key(), Items[Parent].Key())) )
{ // swap Items[Place] and Items[Parent]
heapItemType Temp = Items[Parent];
Items[Parent] = Items[Place];
Items[Place] = Temp;
Place = Parent;
Parent = (Place -1 )/2;
} // end while
++Size;
} // end if
} // end HeapInsert
};
另外两种方法是使用std::priority_queue
或std::make_heap
,std::heap_pop
,std::heap_push
等...两者都可以提供最小堆和最大堆语义。
答案 2 :(得分:0)
现在您的HeapInsert
功能确实:
while ( (Parent >= 0) &&
(Items[Place].Key() > Items[Parent].Key()) )
只需将>
替换为<
。