我该如何编辑此代码以使其成为最小堆
How would I edit this code to make it possible for a min heap?
我有一个最大堆,但我想编辑代码,使其可以生成最小堆。需要明确的是,我想让从Max堆切换到Min堆变得容易,因为我将把它用于两个独立的优先级队列,一个基于Min,另一个基于Max。
这是我的堆.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
堆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) ) ;
}
您想要做的是让heapClass
构造函数接受一个比较函子,该比较函子将在内部保存在类中。然后让heapClass
函数使用函子进行比较。您可以将其设为默认值,使其占用itemClass
中的operator<
。但您也可以传入operator>
来切换排序。
例如,看看Compare functor
是如何传递给std::set
以定义其排序的http://en.cppreference.com/w/cpp/container/set
有一些简单的方法。一种方法是在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
等。两者都可以提供最小堆和最大堆语义。
现在您的HeapInsert
函数执行以下操作:
while ( (Parent >= 0) &&
(Items[Place].Key() > Items[Parent].Key()) )
只需将>
替换为<
即可。
相关文章:
- 我无法在Visual Studio代码中使用CIN输入答案,它说输入您的年龄,但它说只读文本编辑器如何解决这个问题?
- 标准对此指向成员函数类型模板参数有何说明?是我的代码有误,还是 MSVS 16.6 有问题?
- 使用 bash 脚本和测试处理进行代码编辑
- Qt的QFontMetrics::horizontalAdvance()缺少代码编辑器实现
- 无论代码长度如何,以下代码的内存要求有何不同?
- 当光标位置在编辑控件 MFC 中更改时是否有通知代码?
- 我的编辑距离递归代码中的字符类型有问题
- 编辑C Qlist&lt; object*&gt; gt;QML代码和一些QML警告中的模型
- 带有C 代码的编辑组件字节
- 字符 * 和字符串在C++中有何不同?(在描述中编写代码)
- complex.h 适用于 Win32 目标以外的其他编译器,例如代码编辑器工作室 (CCS)
- 代码编辑器工作室 for Arm 中类的 C++ 编译错误
- 支持C和Python之间的跨语言(C)标签的代码编辑器
- 其中是visual studio控件编辑器为visual c++生成的代码
- 是否可以使用十六进制编辑器从exe文件中删除代码?(c++)
- C++代码在 vim 中打开文件,以便在 Xcode 的终端窗口中进行编辑
- 使用 Qt 4.8 (C++) 为 javascript 创建代码编辑器
- C++从代码中编辑代码
- 代码/文本编辑器是否不需要实际的程序本身?
- 将代码的编辑控件在 mingw 中