// priority_queue.h
template
struct priority_queue
{
virtual void insert(T const& e) = 0; // 优先级队列的3个操作接口
virtual T get_max() = 0;
virtual T del_max() = 0;
};
#include"priority_queue.h"
#include"vector.h"
#include
#define min(x,y) ((x)>(y)?(y):(x))
#define max(x,y) ((x)<(y)?(y):(x))
#pragma once
// 外部所需的接口
template Rank adjust_up(T* arr, Rank r) // 第r个元素进行向上调整
{
int p = r / 2; // p means parent(r)
while (arr[p] < arr[r])
{
swap(arr[p], arr[r]);
r = p;
p = r / 2;
}
return r;
}
template Rank adjust_down(T* arr, Rank r, int n) // 前n个元素的第r个元素进行向下调整
{ // 联想堆排序差不多是这个语义
while ( ((r*2+2<=n)&&(arr[r] < arr[(r<<1) + 1])) || ((r*2 + 3 <= n) && (arr[r] < arr[(r<<1) + 2])) )
{
// 此时调整的arr[r]是非叶节点
int lc = (r << 1) + 1; // 这里的都是数组的下标
// 若有rc的话,则lc+1 +1==n
int max_son_index = (lc + 1 == n) ? lc : ((arr[lc] > arr[lc + 1]) ? lc : lc + 1);
swap(arr[r], arr[max_son_index]);
r = max_son_index;
}
return r;
}
template void heapify(T* arr, int n) // 给定n个元素进行建堆
{
for (int i = (n-1) / 2; i >= 0; --i) // 第(n-1)/2为非叶节点
adjust_down(arr, i, n);
}
// 完全二叉堆(大顶堆),形(用什么来存的):vector 神:complete_tree
template struct compl_heap:public vector, public priority_queue
{
compl_heap(){}
compl_heap(T* arr, int n) { vector::copyFrom(arr, 0, n); heapify(arr, n); } // 数组下标从0开始
~compl_heap(){}
void insert(const T& e);
T get_max() { return this->_elem[0]; }
T del_max();
};
template void compl_heap::insert(const T& e)
{
// vector::insert(this->Size() - 1, e); // 写错了!是insert(size)相当于STL里面的push_back
vector::insert(this->_size, e);
adjust_up(this->_elem, this->_size - 1);
}
template T compl_heap::del_max()
{
T old_elem = this->_elem[0];
swap(this->_elem[0], this->_elem[this->_size - 1]);
vector::remove(this->_size - 1);
adjust_down(this->_elem, 0, this->_size); // 前n个元素,arr[0]进行向下调整
return old_elem;
}
template void heap_sort(T* arr, int n)
{
heapify(arr, n); // 建堆
for (int i = n - 1; i >= 0; --i)
{
swap(arr[0], arr[i]);
adjust_down(arr, 0, i); // 向下调整
}
}
int main()
{
// srand((unsigned)time(nullptr));
int arr[] = { 1,6,4,3,7,9 }; // cppreference.com
int len = sizeof(arr) / sizeof(int);
compl_heap c_heap;
// for (int i = 1; i < 8; ++i) c_heap.insert(i*(rand()%20+1));
for (int i = 1; i < 8; ++i) c_heap.insert(i);
c_heap.show();
c_heap.del_max();
c_heap.show();
}