堆 Heap <实现类+测试用例>

堆(Heap)是一种非常有用的数据结构,可以用来设计高效的排序算法和优先队列。一个堆是一棵具有如下性质的二叉树:

  • 它是一棵完全的二叉树
  • 每个节点都有大于等于其它任何自节点
如果一棵二叉树除最后一层外都是满的,切若最后一层不满,所有节点均位于最左边,则称为 完全二叉树(complete binary tree).

堆是二叉树,因此可以用二叉树数据结构描述。但是如果堆的大小预先可知的话,更为有效的描述方法是用数组或向量。 对于位置i的节点,其左孩子在2i+1, 其右孩子在2i+2, 其父节点在(i-1)/2.

程序清单 Heap.h

#ifndef HEAP_H
#define HEAP_H
#include <vector>
#include <stdexcept>
using namespace std;


template<typename T>
class Heap
{
public:
  Heap();
  Heap(T elements[], int arraySize);
  T remove() throw (runtime_error);
  void add(T element);
  int getSize();


private:
  vector<T> v;
};


template <typename T>
Heap<T>::Heap()
{
}


template <typename T>
Heap<T>::Heap(T elements[], int arraySize)
{
  for (int i = 0; i < arraySize; i++)
  {
    add(elements[i]);
  }
}


/* Remove the root from the heap */
template <typename T>
T Heap<T>::remove() throw (runtime_error)
{
  if (v.size() == 0)
    throw runtime_error("Heap is empty");


  T removedElement = v[0];
  v[0] = v[v.size() - 1]; // Move the last to root
  v.pop_back(); // Remove root


  // Maintain the heap property
  int currentIndex = 0;
  while (currentIndex < v.size())
  {
    int leftChildIndex = 2 * currentIndex + 1;
    int rightChildIndex = 2 * currentIndex + 2;


    // Find the maximum between two children
    if (leftChildIndex >= v.size()) break; // The tree is a heap
    int maxIndex = leftChildIndex;
    if (rightChildIndex < v.size())
    {
      if (v[maxIndex] < v[rightChildIndex])
      {
        maxIndex = rightChildIndex;
      }
    }


    // Swap if the current node is less than the maximum
    if (v[currentIndex] < v[maxIndex])
    {
      T temp = v[maxIndex];
      v[maxIndex] = v[currentIndex];
      v[currentIndex] = temp;
      currentIndex = maxIndex;
    }
    else
      break; // The tree is a heap
  }


  return removedElement;
}


/* Insert element into the heap and maintain the heap property */
template <typename T>
void Heap<T>::add(T element)
{
  v.push_back(element); // Append element to the heap
  int currentIndex = v.size() - 1; // The index of the last node


  // Maintain the heap property
  while (currentIndex > 0)
  {
    int parentIndex = (currentIndex - 1) / 2;
    // Swap if the current object is greater than its parent
    if (v[currentIndex] > v[parentIndex] )
    {
      T temp = v[currentIndex];
      v[currentIndex] = v[parentIndex];
      v[parentIndex] = temp;
    }
    else
      break; // the tree is a heap now


    currentIndex = parentIndex;
  }
}


/* Get the number of element in the heap */
template <typename T>
int Heap<T>::getSize()
{
  return v.size();
}


#endif

程序清单 TestHeap.cpp
#include<iostream>
#include<string>
#include "Heap.h"
using namespace std;

int main(){
Heap<string> heap1;
    heap1.add("George");
    heap1.add("Michael");
    heap1.add("Tom");
    heap1.add("Adam");
    heap1.add("Jones");
    heap1.add("Peter");

    while(heap1.getSize() > 0)
        cout<<heap1.remove()<< " ";
    cout<<endl;

    int numbers[] = {8,9,2,3,4,1,5,6,7};
    Heap<int> heap2(numbers, 9);
    while(heap2.getSize() > 0)
        cout<<heap2.remove()<< " ";
    cout<<endl;

    return 0;
}<u>
</u>



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值