大根堆实现
MaxHeap.h
#pragma once
#include<iostream>
using namespace std;
template<typename T>
class MaxHeap {
private:
//堆
T* heap;
//实际容量
int size;
//总容量
int maxCapacity;
//最大堆的下调算法
void filterDown(const int &start,const int &end);
//最大堆的向上调整算法(从start开始向上直到0,调整堆)
void filterUp(const int &start);
public:
MaxHeap(int capacity=30);
~MaxHeap();
//获得data的索引,没有就返回-1
int getIndex(const T &data) const;
//插入data,成功返回true,失败返回false
bool insert(const T &data);
//移除data,成功返回true,失败返回false
bool remove(const T &data);
//打印大根堆
void print()const;
};
MaxHeap.cpp
#include "MaxHeap.h"
template<typename T>
MaxHeap<T>::MaxHeap(int capacity) {
size = 0;
maxCapacity = capacity;
heap = new T[capacity];
}
template<typename T>
MaxHeap<T>::~MaxHeap() {
size = maxCapacity = 0;
delete[] heap;
}
//最大堆的向上调整算法(从start开始向上直到0,调整堆)
template<typename T>
void MaxHeap<T>::filterUp(const int &start) {
//当前节点索引
int current = start;
//当前节点父亲
int parent = (start - 1) >> 1;
//当前节点值
T temp = heap[current];
while (current > 0) {
//节点比父亲小
if (temp <= heap[parent])break;
//节点比父亲大
heap[current] = heap[parent];
current = parent;
parent = (parent - 1) >> 1;
}
heap[current] = temp;
}
//插入data,成功返回true,失败返回false
template<typename T>
bool MaxHeap<T>::insert(const T &data) {
if (size == maxCapacity)return false;
heap[size] = data;
filterUp(size);
++size;
return true;
}
//获得data的索引,没有就返回-1
template<typename T>
int MaxHeap<T>::getIndex(const T &data) const {
for (int i = 0; i < size; ++i) {
if (data == heap[i])return i;
}
return -1;
}
//最大堆的下调算法
template<typename T>
void MaxHeap<T>::filterDown(const int &start, const int &end) {
//当前节点
int current = start;
//左孩子
int child = start << 1 | 1;
//当前节点值
T temp = heap[current];
while (child <= end) {
//如果有右孩子,且右孩子比左孩子大,则son=右孩子
if (child < end&&heap[child] < heap[child+1])++child;
//调整结束了
if (temp > heap[child])break;
heap[current] = heap[child];
current = child;
child = current << 1 | 1;
}
heap[current] = temp;
}
//移除data,成功返回true,失败返回false
template<typename T>
bool MaxHeap<T>::remove(const T &data) {
if (size <= 0)return false;
int index = getIndex(data);
if (index < 0)return false;
--size;
heap[index] = heap[size];
filterDown(index, size - 1);
return true;
}
//打印大根堆
template<typename T>
void MaxHeap<T>::print()const {
for (int i = 0; i < size; ++i) {
cout << heap[i] << ' ';
}
cout << endl;
}
main.cpp
#include<iostream>
#include "MaxHeap.cpp"
using namespace std;
int main() {
int a[] = { 10, 40, 30, 60, 90, 70, 20, 50, 80 };
int i, len = sizeof(a) / sizeof(a[0]);
MaxHeap<int>* tree = new MaxHeap<int>();
cout << "----依次添加----" << endl;
for (int c : a) {
cout << c << ' ';
tree->insert(c);
}
cout << endl;
cout << "----最大堆----" << endl;
tree->print();
i = 85;
tree->insert(i);
cout << "添加元素:" << i << endl;
cout << "----最大堆----" << endl;
tree->print();
i = 60;
tree->remove(i);
cout << "删除元素:" << i << endl;
cout << "----最大堆----" << endl;
tree->print();
return 0;
}
堆排序(从小到大)
#include<iostream>
using namespace std;
template<typename T>
void heapAdjust(T a[], int parent, int len) {
T temp = a[parent];
//左孩子,从0开始的节点左孩子是2*i+1有孩子是2*i+2
int child = 2 * parent + 1;
while (child < len) {
//如果右孩子比左孩子大
if (child + 1 < len&&a[child] < a[child + 1])++child;
//如果已经比孩子大了,退出
if (temp >= a[child])break;
a[parent] = a[child];
parent = child;
child = 2 * child + 1;
}
a[parent] = temp;
}
template<typename T>
void heapSort(T a[], int n) {
//初建堆
for (int i = n / 2 - 1; i >= 0; --i)heapAdjust(a, i, n);
for (int i = n - 1; i >= 0; --i) {
//根和最后一个节点交换(把最大的换下去)
swap(a[i], a[0]);
//重新调整
heapAdjust(a, 0, i);
//for (int j = 0; j < n; ++j)cout << a[j] << ' ';
//cout << endl;
}
}
int main() {
/*
12
46 74 16 53 14 26 40 38 86 65 27 34
*/
int n;
cin >> n;
int *a = new int[n];
for (int i = 0; i < n; ++i)cin >> a[i];
cout << endl << endl << endl;
heapSort(a, n);
for (int j = 0; j < n; ++j)cout << a[j] << ' ';
cout << endl;
delete[] a;
return 0;
}