C++实现堆、最大堆、最小堆 -- 堆排序插入删除操作
程序员文章站
2024-02-13 16:13:22
...
堆是一种经过排序的完全二叉树,其中任一非终端节点的数据值均不大于(或不小于)其左孩子和右孩子节点的值。
最大堆和最小堆是二叉堆的两种形式。
最大堆:根结点的键值是所有堆结点键值中最大者。
最小堆:根结点的键值是所有堆结点键值中最小者。
而最大-最小堆集结了最大堆和最小堆的优点,这也是其名字的由来。
最大-最小堆是最大层和最小层交替出现的二叉树,即最大层结点的儿子属于最小层,最小层结点的儿子属于最大层。
以最大(小)层结点为根结点的子树保有最大(小)堆性质:根结点的键值为该子树结点键值中最大(小)项。
一:堆
我们构建一个堆类,用最大堆和最小堆来继承他。
#ifndef _HEAP_H
#define _HEAP_H
#include <iostream>
using namespace std;
enum{DEFAULT_SIZE = 10};
template <typename T>
class Heap{
public:
Heap() = default;
virtual ~Heap() = default;
public:
virtual void show_heap()const = 0;
virtual bool insert_heap(const T&) = 0;
virtual bool remove_heap(T &) = 0;
};
//public interface
#endif /*Heap.h*/
二:最大堆
下面是最大堆的实现:
#ifndef _MAXHEAP_H
#define _MAXHEAP_H
#include <iostream>
#include "Heap.h"
template <typename T>
class MaxHeap : public Heap<T>{
public:
MaxHeap(int);
MaxHeap(const T [], const int);
~MaxHeap();
public:
bool insert_heap(const T&);
bool remove_heap(T &);
void show_heap()const;
protected:
void sift_down(int, int);
void sift_up(int);
private:
T *heap;
int size;
int capacity;
};
//public interface
template <typename T>
MaxHeap<T>::MaxHeap(int sz = DEFAULT_SIZE)
{
capacity = sz > DEFAULT_SIZE ? sz : DEFAULT_SIZE;
heap = new T[capacity];
assert(heap != NULL);
size = 0;
}
template <typename T>
MaxHeap<T>::MaxHeap(const T arr[], const int arrSize)
{
capacity = arrSize > DEFAULT_SIZE ? arrSize : DEFAULT_SIZE;
heap = new T[capacity];
assert(heap != NULL);
size = arrSize;
for(int i=0; i<size; ++i)
heap[i] = arr[i];
int curPos = size/2 - 1;
while(curPos >= 0){
sift_down(curPos, size-1);
--curPos;
}
}
template <typename T>
MaxHeap<T>::~MaxHeap()
{
delete []heap;
heap = NULL;
capacity = size = 0;
}
template <typename T>
bool MaxHeap<T>::insert_heap(const T& val)
{
if(size >= capacity)
return false;
heap[size] = val;
sift_up(size);
++size;
return true;
}
template <typename T>
bool MaxHeap<T>::remove_heap(T &val)
{
if(size <= 0)
return false;
val = heap[0];
heap[0] = heap[size-1];
--size;
sift_down(0, size-1);
return true;
}
template <typename T>
void MaxHeap<T>::show_heap()const
{
for(int i=0; i<size; ++i)
std::cout << heap[i] << " ";
std::cout << std::endl;
}
//protected interface
template <typename T>
void MaxHeap<T>::sift_down(int start, int end)
{
int i = start;
int j = i*2 + 1;
T tmp = heap[i];
while(j <= end){
if(j+1 <= end && heap[j] < heap[j+1])
++j;
if(tmp < heap[j])
heap[i] = heap[j];
else
break;
i = j;
j = j*2 + 1;
}
heap[i] = tmp;
}
template <typename T>
void MaxHeap<T>::sift_up(int start)
{
int j = start;
int i = (start-1) / 2;
T tmp = heap[j];
while(j > 0){
if(tmp < heap[i])
break;
else
heap[j] = heap[i];
j = i;
i = (i-1) / 2;
}
heap[j] = tmp;
}
#endif /*MaxHeap.h*/
三:最小堆
下面是最小堆的实现:
#ifndef _MINHEAP_H
#define _MINHEAP_H
#include <assert.h>
#include "Heap.h"
template <typename T>
class MinHeap : public Heap<T>{
public:
MinHeap(int);
MinHeap(const T [], const int );
~MinHeap();
public:
bool insert_heap(const T&);
bool remove_heap(T &);
void show_heap()const;
protected:
void sift_down(int, int);
void sift_up(int);
private:
T* heap;
int size;
int capacity;
};
//interface
template <typename T>
MinHeap<T>::MinHeap(int sz = DEFAULT_SIZE)
{
capacity = sz > DEFAULT_SIZE ? sz : DEFAULT_SIZE;
heap = new T[capacity];
assert(heap != NULL);
size = 0;
}
template <typename T>
MinHeap<T>::MinHeap(const T arr[], const int arrSize)
{
capacity = arrSize > DEFAULT_SIZE ? arrSize : DEFAULT_SIZE;
heap = new T[capacity];
assert(heap != NULL);
size = arrSize;
for(int i=0; i<arrSize; ++i)
heap[i] = arr[i];
int curPos = arrSize/2 - 1;
while(curPos >= 0){
sift_down(curPos, arrSize-1);
--curPos;
}
}
template <typename T>
MinHeap<T>::~MinHeap()
{
delete []heap;
heap = NULL;
capacity = size = 0;
}
template <typename T>
bool MinHeap<T>::insert_heap(const T& val)
{
if(size >= capacity)
return false;
heap[size] = val;
sift_up(size);
++size;
return true;
}
template <typename T>
bool MinHeap<T>::remove_heap(T& val)
{
if(size <= 0)
return false;
val = heap[0];
heap[0] = heap[size-1];
--size;
sift_down(0, size-1);
return true;
}
template <typename T>
void MinHeap<T>::show_heap()const
{
for(int i=0; i<size; ++i)
std::cout << heap[i] << " ";
std::cout << std::endl;
}
//protected interface
template <typename T>
void MinHeap<T>::sift_down(int start, int end)
{
int i = start;
int j = start*2 + 1;
T tmp = heap[i];
while(j <= end){
if(j+1 < end && heap[j] > heap[j+1])
++j;
if(tmp < heap[j])
break;
else
heap[i] = heap[j];
i = j;
j = j*2 + 1;
}
heap[i] = tmp;
}
template <typename T>
void MinHeap<T>::sift_up(int start)
{
int j = start;
int i = (start-1) / 2;
T tmp = heap[j];
while(j > 0){
if(tmp > heap[i])
break;
else
heap[j] = heap[i];
j = i;
i = (i-1) / 2;
}
heap[j] = tmp;
}
#endif
四:测试如下:
#include "MinHeap.h"
#include "MaxHeap.h"
#include <iostream>
using namespace std;
int main()
{
int array[] = {23, 9, 34, 2, 56, 89, 35, 54};
cout << "***************************MinHeap***************************" << endl;
MinHeap<int> min_heap(array, sizeof(array)/sizeof(int));
min_heap.show_heap();
min_heap.insert_heap(1);
min_heap.show_heap();
for(int i=0; i<9; ++i){
int val;
min_heap.remove_heap(val);
cout << val << " ";
}
cout << endl;
MaxHeap<int> max_heap(array, sizeof(array)/sizeof(int));
cout << "***************************MaxHeap**************************" << endl;
max_heap.show_heap();
max_heap.insert_heap(99);
max_heap.show_heap();
for(int i=0; i<9; ++i){
int val;
max_heap.remove_heap(val);
cout << val << " ";
}
cout << endl;
return 0;
}
结果如下:
下一篇: OpenSSL-证书链