方法一
//一个大顶堆的例子
#include <iostream>#include <algorithm>
using namespace std;
const int maxsize = 100;
int heap[maxsize];
int size = 0;
//在堆heap中插入data
void insertHeap(int *heap, int data);
//获得最大值
int getMax(int *heap);
//从堆中删除最大值
void deleteMax(int *heap);
int main()
{
int buf[8] = {16, 21, 12, 30, 13, 15, 10, 25};
for (int i = 0; i < 8; i++)
{
insertHeap(heap, buf[i]);
}
while (size > 0)
{
cout << getMax(heap) << " ";
deleteMax(heap);
}
return 0;
}
//获得最大值
int getMax(int *heap)
{
return heap[0];
}
//在堆heap中插入data
void insertHeap(int *heap, int data)
{//新加入的元素放在数组的最后
int k = size;
heap[k] = data;
size++;
//上筛
while (k > 0)
{//如果没有到达根结点,继续上筛
int parent = (k - 1) / 2;//得到父节点的下标
if (heap[parent] > heap[k])
{//如果父节点的值大于新加入元素的值,堆序性存在,退出循环
break;
}
swap(heap[parent], heap[k]);//交换heap[parent]和heap[k]
k = parent;
}
}
//从堆中删除最大值
void deleteMax(int *heap)
{
swap(heap[0], heap[size - 1]);//交换堆顶和堆的最后一个元素
--size;//删除堆中的最后一个元素
//下筛
int parent = 0;
int left = 2 * parent + 1;
while (left < size)
{//当左子树的编号在堆的下标范围之内,说明parent是叶子结点
int k;
int right = left + 1;
if (right >= size)
{//没有右孩子
if (heap[parent] > heap[left])
{//父结点的值大于左孩子的值,堆序性存在
break;
}
k = left;
swap(heap[parent], heap[k]);//交换父结点和左孩子的值
}
else
{//有左右孩子
if (heap[parent] > heap[left] && heap[parent] > heap[right])
{//父结点的值大于左右孩子的值,堆序性存在
break;
}
//把父结点的值和左右孩子中最大的值交换
k = heap[left] > heap[right] ? left : right;
swap(heap[parent], heap[k]);
}
parent = k;//下一次要下筛的结点编号
left = 2 * parent + 1;}
}
方法二
//一个大顶堆的例子
#include <iostream>
#include <algorithm>
using namespace std;
const int maxsize = 100;
struct Heap
{
int *heap;
int size;
};
//初始化堆
void initHeap(Heap* pHeap);
//销毁堆
void destroyHeap(Heap* pHeap);
//在堆heap中插入data
void insertHeap(Heap* pHeap, int data);
//获得最大值
int getMax(Heap* pHeap);
//从堆中删除最大值
void deleteMax(Heap* pHeap);
int main()
{
int buf[8] = {16, 21, 12, 30, 13, 15, 10, 25};
Heap myHeap;
initHeap(&myHeap);
for (int i = 0; i < 8; i++)
{
insertHeap(&myHeap, buf[i]);
}
while (myHeap.size > 0)
{
cout << getMax(&myHeap) << " ";
deleteMax(&myHeap);
}
destroyHeap(&myHeap);
return 0;
}
//获得最大值
int getMax(Heap* pHeap)
{
return pHeap->heap[0];
}
//在堆heap中插入data
void insertHeap(Heap* pHeap, int data)
{//新加入的元素放在数组的最后
int k = pHeap->size;
pHeap->heap[k] = data;
pHeap->size++;
//上筛
while (k > 0)
{//如果没有到达根结点,继续上筛
int parent = (k - 1) / 2;//得到父节点的下标
if (pHeap->heap[parent] > pHeap->heap[k])
{//如果父节点的值大于新加入元素的值,堆序性存在,退出循环
break;
}
swap(pHeap->heap[parent], pHeap->heap[k]);//交换heap[parent]和heap[k]
k = parent;
}
}
//从堆中删除最大值
void deleteMax(Heap* pHeap)
{
swap(pHeap->heap[0], pHeap->heap[pHeap->size - 1]);//交换堆顶和堆的最后一个元素
--(pHeap->size);//删除堆中的最后一个元素
//下筛
int parent = 0;
int left = 2 * parent + 1;
while (left < pHeap->size)
{//当左子树的编号在堆的下标范围之内,说明parent是叶子结点
int k;
int right = left + 1;
if (right >= pHeap->size)
{//没有右孩子
if (pHeap->heap[parent] > pHeap->heap[left])
{//父结点的值大于左孩子的值,堆序性存在
break;
}
k = left;
swap(pHeap->heap[parent], pHeap->heap[k]);//交换父结点和左孩子的值
}
else
{//有左右孩子
if (pHeap->heap[parent] > pHeap->heap[left] && pHeap->heap[parent] > pHeap->heap[right])
{//父结点的值大于左右孩子的值,堆序性存在
break;
}
//把父结点的值和左右孩子中最大的值交换
k = pHeap->heap[left] > pHeap->heap[right] ? left : right;
swap(pHeap->heap[parent], pHeap->heap[k]);
}
parent = k;//下一次要下筛的结点编号
left = 2 * parent + 1;
}
}
//初始化堆
void initHeap(Heap* pHeap)
{
pHeap->heap = new int[maxsize];
pHeap->size = 0;
}
//销毁堆
void destroyHeap(Heap* pHeap)
{
delete pHeap->heap;
pHeap->heap = NULL;
pHeap->size = 0;
}
方法三
//一个大顶堆的例子
#include <iostream>
#include <algorithm>
using namespace std;
const int maxsize = 100;
class Heap
{
public:
Heap();//初始化堆
~Heap();//销毁堆
void insertHeap(int data);//在堆heap中插入data
int getMax();//获得最大值
void deleteMax();//从堆中删除最大值
public:
int *heap;
int size;
};
int main()
{
int buf[8] = {16, 21, 12, 30, 13, 15, 10, 25};
Heap myHeap;
for (int i = 0; i < 8; i++)
{
myHeap.insertHeap(buf[i]);
}
while (myHeap.size > 0)
{
cout << myHeap.getMax() << " ";
myHeap.deleteMax();
}
return 0;
}
//获得最大值
int Heap::getMax()
{
return heap[0];
}
//在堆heap中插入data
void Heap::insertHeap(int data)
{//新加入的元素放在数组的最后
int k = size;
heap[k] = data;
size++;
//上筛
while (k > 0)
{//如果没有到达根结点,继续上筛
int parent = (k - 1) / 2;//得到父节点的下标
if (heap[parent] > heap[k])
{//如果父节点的值大于新加入元素的值,堆序性存在,退出循环
break;
}
swap(heap[parent], heap[k]);//交换heap[parent]和heap[k]
k = parent;
}
}
//从堆中删除最大值
void Heap::deleteMax()
{
swap(heap[0], heap[size - 1]);//交换堆顶和堆的最后一个元素
--size;//删除堆中的最后一个元素
//下筛
int parent = 0;
int left = 2 * parent + 1;
while (left < size)
{//当左子树的编号在堆的下标范围之内,说明parent是叶子结点
int k;
int right = left + 1;
if (right >= size)
{//没有右孩子
if (heap[parent] > heap[left])
{//父结点的值大于左孩子的值,堆序性存在
break;
}
k = left;
swap(heap[parent], heap[k]);//交换父结点和左孩子的值
}
else
{//有左右孩子
if (heap[parent] > heap[left] && heap[parent] > heap[right])
{//父结点的值大于左右孩子的值,堆序性存在
break;
}
//把父结点的值和左右孩子中最大的值交换
k = heap[left] > heap[right] ? left : right;
swap(heap[parent], heap[k]);
}
parent = k;//下一次要下筛的结点编号
left = 2 * parent + 1;
}
}
//销毁堆
void destroyHeap(Heap* pHeap)
{
delete pHeap->heap;
pHeap->heap = NULL;
pHeap->size = 0;
}
Heap::Heap()
{
heap = new int[maxsize];
size = 0;
}
Heap::~Heap()
{
delete[] heap;
heap = NULL;
size = 0;
}
方法四
//一个大顶堆的例子
#include <iostream>
#include <algorithm>
#include <cstdlib>
#include <ctime>
using namespace std;
class Heap
{
public:
Heap();//构造函数,初始化堆
~Heap();//析构函数,销毁堆
void insertHeap(int data);//在堆heap中插入data
inline int getMax();//获得最大值
void deleteMax();//从堆中删除最大值
inline int getSize();//定义成内联函数,以节约函数调用的时间
void reSize();//空间不够时,重新分配空间
private:
int *heap; //指向内存空间的指针
int size; //堆中实际拥有的元素个数
int capacity;//分配给heap指针的内存空间元素个数
};
int main()
{
srand(time(NULL));//设置随机数的种子
Heap myHeap;//定义一个 Heap 类的对象 myHeap
for (int i = 1; i <= 25; i++)
{//向堆中插入25个 0 ~ 99 之间的随机数,会造成2次内存的重新分配
myHeap.insertHeap(rand() % 100);
}
while (myHeap.getSize() > 0)
{
cout << myHeap.getMax() << " ";
myHeap.deleteMax();
}
return 0;
}
//构造函数
Heap::Heap()
{
capacity = 10;//初始化时,堆中有10个元素的空间
heap = new int[capacity];//分配内存空间
size = 0;
}
//析构函数
Heap::~Heap()
{
delete[] heap;
heap = NULL;
size = 0;
}
//空间不够时,重新分配空间
void Heap::reSize()
{
capacity *= 2;//空间增大2倍
int *temp = heap;
heap = new int[capacity];//重新申请空间
for (int i = 0; i < size; i++)
{//复制原内存空间中的元素到新空间
heap[i] = temp[i];
}
delete[] temp;//释放原内存空间
}
inline int Heap::getSize()
{
return size;
}
//获得最大值
int Heap::getMax()
{
return heap[0];
}
//在堆heap中插入data
void Heap::insertHeap(int data)
{//新加入的元素放在数组的最后
if (size + 1 > capacity)
{//如果空间已满,则重新分配空间
reSize();
}
int k = size;
heap[k] = data;
size++;
//上筛
while (k > 0)
{//如果没有到达根结点,继续上筛
int parent = (k - 1) / 2;//得到父节点的下标
if (heap[parent] > heap[k])
{//如果父节点的值大于新加入元素的值,堆序性存在,退出循环
break;
}
swap(heap[parent], heap[k]);//交换heap[parent]和heap[k]
k = parent;
}
}
//从堆中删除最大值
void Heap::deleteMax()
{
swap(heap[0], heap[size - 1]);//交换堆顶和堆的最后一个元素
--size;//删除堆中的最后一个元素
//下筛
int parent = 0;
int left = 2 * parent + 1;
while (left < size)
{//当左子树的编号在堆的下标范围之内,说明parent是叶子结点
int k;
int right = left + 1;
if (right >= size)
{//没有右孩子
if (heap[parent] > heap[left])
{//父结点的值大于左孩子的值,堆序性存在
break;
}
k = left;
swap(heap[parent], heap[k]);//交换父结点和左孩子的值
}
else
{//有左右孩子
if (heap[parent] > heap[left] && heap[parent] > heap[right])
{//父结点的值大于左右孩子的值,堆序性存在
break;
}
//把父结点的值和左右孩子中最大的值交换
k = heap[left] > heap[right] ? left : right;
swap(heap[parent], heap[k]);
}
parent = k;//下一次要下筛的结点编号
left = 2 * parent + 1;
}
}