#include <iostream>
#include <cstdlib>
//функтор по-умолчанию от наибольшего к меньшему
template<typename T>
struct pcmp {
bool operator () (const T& a, const T& b)const{
return (a > b);
}
};
//приоритетная очредь на базе бинарной кучи
template<typename T, typename Cmp = pcmp<T> >
class pqueue {
private:
T* arr;
size_t cnt;
size_t mem;
Cmp cmp;
public:
pqueue(void):arr(NULL),
cnt(0),
mem(16){}
pqueue(const T* f, const T* l):arr(NULL),
cnt(0),
mem(16){
this->copy(f, l);
}
~pqueue(){
this->clear();
}
pqueue(const pqueue&);
pqueue& operator = (const pqueue&);
public:
//добавление
bool push(const T& val){
if(! this->_alloc_array(1))
return false;
arr[cnt++] = val;
size_t i = cnt - 1;
size_t p = (i - 1) >> 1;
while((i > 0) && cmp(val, arr[p])){
std::swap(arr[p], arr[i]);
i = p;
p = (p - 1) >> 1;
}
return true;
}
//удаление
void pop(void){
if(cnt > 0){
arr[0] = arr[--cnt];
this->heapify(0);
}
if(! cnt)
this->clear();
}
//копирование массива
bool copy(const T* f, const T* l){
size_t num = (size_t)(l - f);
cnt = 0;
if(! this->_alloc_array(num))
return false;
T* p = arr;
while(f != l)
*p++ = *f++;
cnt = num;
for(size_t i = cnt >> 1; i > 0; --i)
this->heapify(i);
this->heapify(0);
return true;
}
//удаление всех
void clear(void){
if(arr != NULL)
delete[] arr;
arr = NULL;
cnt = 0;
mem = 16;
}
T& top(void) { return arr[0]; }
T& top(void) const { return arr[0]; }
size_t size(void) const {
return cnt;
}
bool empty(void) const {
return (cnt == 0);
}
private:
bool _alloc_array(size_t n){
size_t tmem;
if(arr == NULL){
tmem = mem;
if(n > tmem)
tmem = n;
arr = new (std::nothrow) T[tmem];
if(arr == NULL)
return false;
mem = tmem;
} else if((cnt + n) >= mem){
tmem = cnt + n + mem / 3;
T* tmp = new (std::nothrow) T[tmem];
if(tmp == NULL)
return false;
T* p = tmp;
T* e = arr + cnt;
for(T* i = arr; i != e; ++i)
*p++ = *i;
delete[] arr;
arr = tmp;
mem = tmem;
}
return true;
}
void heapify(size_t i){
size_t li, ri, big;
while(1) {
li = (i << 1) + 1;
ri = li + 1;
if((li < cnt) && cmp(arr[li], arr[i]))
big = li;
else
big = i;
if((ri < cnt) && cmp(arr[ri], arr[big]))
big = ri;
if(big != i){
std::swap(arr[big], arr[i]);
i = big;
}else
break;
}
}
};
// от наименьшего к большему
struct intcmp {
bool operator () (int a, int b)const{
return (a < b);
}
};
int main(void){
pqueue<char> pch;
for(int i = 0; i < 30; ++i)
pch.push('A' + (char)(std::rand() % 26));
while(! pch.empty()){
std::cout << pch.top();
pch.pop();
}
std::cout << std::endl;
//...
int A[] = { 5, 2, 8, 6, 7, 1, 9, 3, 0, 4 };
pqueue<int, intcmp> pq(A, A + sizeof(A)/sizeof(A[0]));
while(! pq.empty()){
std::cout << pq.top() << ' ';
pq.pop();
}
return 0;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8Y3N0ZGxpYj4KCi8v0YTRg9C90LrRgtC+0YAg0L/Qvi3Rg9C80L7Qu9GH0LDQvdC40Y4g0L7RgiDQvdCw0LjQsdC+0LvRjNGI0LXQs9C+INC6INC80LXQvdGM0YjQtdC80YMKdGVtcGxhdGU8dHlwZW5hbWUgVD4Kc3RydWN0IHBjbXAgewoJYm9vbCBvcGVyYXRvciAoKSAoY29uc3QgVCYgYSwgY29uc3QgVCYgYiljb25zdHsKCQlyZXR1cm4gKGEgPiBiKTsKCX0KfTsKCi8v0L/RgNC40L7RgNC40YLQtdGC0L3QsNGPINC+0YfRgNC10LTRjCDQvdCwINCx0LDQt9C1INCx0LjQvdCw0YDQvdC+0Lkg0LrRg9GH0LgKdGVtcGxhdGU8dHlwZW5hbWUgVCwgdHlwZW5hbWUgQ21wID0gcGNtcDxUPiA+CmNsYXNzIHBxdWV1ZSB7CnByaXZhdGU6CglUKiAgICAgYXJyOwoJc2l6ZV90IGNudDsKCXNpemVfdCBtZW07CglDbXAgICAgY21wOwpwdWJsaWM6CglwcXVldWUodm9pZCk6YXJyKE5VTEwpLAoJICAgICAgICAgICAgIGNudCgwKSwKCQkJCSBtZW0oMTYpe30KCXBxdWV1ZShjb25zdCBUKiBmLCBjb25zdCBUKiBsKTphcnIoTlVMTCksCgkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY250KDApLAoJICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1lbSgxNil7CgkJdGhpcy0+Y29weShmLCBsKTsKCX0KCX5wcXVldWUoKXsKCQl0aGlzLT5jbGVhcigpOwoJfQoJcHF1ZXVlKGNvbnN0IHBxdWV1ZSYpOwoJcHF1ZXVlJiBvcGVyYXRvciA9IChjb25zdCBwcXVldWUmKTsKcHVibGljOgoJCgkvL9C00L7QsdCw0LLQu9C10L3QuNC1Cglib29sIHB1c2goY29uc3QgVCYgdmFsKXsJCgkJaWYoISB0aGlzLT5fYWxsb2NfYXJyYXkoMSkpCgkJCXJldHVybiBmYWxzZTsKCgkJYXJyW2NudCsrXSA9IHZhbDsKCQlzaXplX3QgICBpID0gY250IC0gMTsKCQlzaXplX3QgICBwID0gKGkgLSAxKSA+PiAxOwoJCXdoaWxlKChpID4gMCkgJiYgY21wKHZhbCwgYXJyW3BdKSl7CgkJCXN0ZDo6c3dhcChhcnJbcF0sIGFycltpXSk7CgkJCWkgPSBwOwoJCQlwID0gKHAgLSAxKSA+PiAxOwoJCX0KCQlyZXR1cm4gdHJ1ZTsKCX0KCgkvL9GD0LTQsNC70LXQvdC40LUKCXZvaWQgcG9wKHZvaWQpewoJCWlmKGNudCA+IDApewoJCQlhcnJbMF0gPSBhcnJbLS1jbnRdOwoJCQl0aGlzLT5oZWFwaWZ5KDApOwoJCX0KCQlpZighIGNudCkKCQkJdGhpcy0+Y2xlYXIoKTsKCX0KCgkvL9C60L7Qv9C40YDQvtCy0LDQvdC40LUg0LzQsNGB0YHQuNCy0LAKCWJvb2wgY29weShjb25zdCBUKiBmLCBjb25zdCBUKiBsKXsKCQlzaXplX3QgbnVtID0gKHNpemVfdCkobCAtIGYpOwoJCWNudCA9IDA7CgkJaWYoISB0aGlzLT5fYWxsb2NfYXJyYXkobnVtKSkKCQkJcmV0dXJuIGZhbHNlOwoKCQlUKiBwID0gYXJyOwoJCXdoaWxlKGYgIT0gbCkKCQkJKnArKyA9ICpmKys7CgkJY250ID0gbnVtOwoKCQlmb3Ioc2l6ZV90IGkgPSBjbnQgPj4gMTsgaSA+IDA7IC0taSkgCgkJCXRoaXMtPmhlYXBpZnkoaSk7CgkJdGhpcy0+aGVhcGlmeSgwKTsKCQlyZXR1cm4gdHJ1ZTsKCX0KCgkvL9GD0LTQsNC70LXQvdC40LUg0LLRgdC10YUKCXZvaWQgY2xlYXIodm9pZCl7CgkJaWYoYXJyICE9IE5VTEwpCgkJCWRlbGV0ZVtdIGFycjsKCQlhcnIgPSBOVUxMOwoJCWNudCA9IDA7CgkJbWVtID0gMTY7Cgl9CgoJVCYgdG9wKHZvaWQpIHsgcmV0dXJuIGFyclswXTsgfQoJVCYgdG9wKHZvaWQpIGNvbnN0IHsgcmV0dXJuIGFyclswXTsgfQoKCXNpemVfdCBzaXplKHZvaWQpIGNvbnN0IHsKCQlyZXR1cm4gY250OwoJfQoKCWJvb2wgZW1wdHkodm9pZCkgY29uc3QgewoJCXJldHVybiAoY250ID09IDApOwoJfQoKcHJpdmF0ZToKCQoJYm9vbCBfYWxsb2NfYXJyYXkoc2l6ZV90IG4pewoJCXNpemVfdCB0bWVtOwoJCWlmKGFyciA9PSBOVUxMKXsKCQkJdG1lbSA9IG1lbTsKCQkJaWYobiA+IHRtZW0pCgkJCQl0bWVtID0gbjsKCQkJYXJyID0gbmV3IChzdGQ6Om5vdGhyb3cpIFRbdG1lbV07CgkJCWlmKGFyciA9PSBOVUxMKQoJCQkJcmV0dXJuIGZhbHNlOwoJCQltZW0gPSB0bWVtOwoJCX0gZWxzZSBpZigoY250ICsgbikgPj0gbWVtKXsKCQkJdG1lbSAgID0gY250ICsgbiArIG1lbSAvIDM7CgkJCVQqIHRtcCA9IG5ldyAoc3RkOjpub3Rocm93KSBUW3RtZW1dOwoJCQlpZih0bXAgPT0gTlVMTCkKCQkJCXJldHVybiBmYWxzZTsKCgkJCVQqIHAgPSB0bXA7CgkJCVQqIGUgPSBhcnIgKyBjbnQ7CgkJCWZvcihUKiBpID0gYXJyOyBpICE9IGU7ICsraSkKCQkJCSpwKysgPSAqaTsKCgkJCWRlbGV0ZVtdIGFycjsKCQkJYXJyID0gdG1wOwoJCQltZW0gPSB0bWVtOwoJCX0KCQlyZXR1cm4gdHJ1ZTsKCX0KCgl2b2lkIGhlYXBpZnkoc2l6ZV90IGkpewoJCXNpemVfdCBsaSwgcmksIGJpZzsKCgkJd2hpbGUoMSkgewoJCQlsaSA9IChpIDw8IDEpICsgMTsKCQkJcmkgPSBsaSArIDE7CgkJCWlmKChsaSA8IGNudCkgJiYgY21wKGFycltsaV0sIGFycltpXSkpCgkJCQliaWcgPSBsaTsKCQkJZWxzZQoJCQkJYmlnID0gaTsKCgkJCWlmKChyaSA8IGNudCkgJiYgY21wKGFycltyaV0sIGFycltiaWddKSkKCQkJCWJpZyA9IHJpOwoKCQkJaWYoYmlnICE9IGkpewoJCQkJc3RkOjpzd2FwKGFycltiaWddLCBhcnJbaV0pOwoJCQkJaSA9IGJpZzsKCQkJfWVsc2UKCQkJCWJyZWFrOwoJCX0KCX0KfTsKCi8vINC+0YIg0L3QsNC40LzQtdC90YzRiNC10LPQviDQuiDQsdC+0LvRjNGI0LXQvNGDCnN0cnVjdCBpbnRjbXAgewoJYm9vbCBvcGVyYXRvciAoKSAoaW50IGEsIGludCBiKWNvbnN0ewoJCXJldHVybiAoYSA8IGIpOwoJfQp9OwoKCmludCBtYWluKHZvaWQpewoJcHF1ZXVlPGNoYXI+IHBjaDsKCWZvcihpbnQgaSA9IDA7IGkgPCAzMDsgKytpKQoJCXBjaC5wdXNoKCdBJyArIChjaGFyKShzdGQ6OnJhbmQoKSAlIDI2KSk7CQoJCQoJd2hpbGUoISBwY2guZW1wdHkoKSl7CgkJc3RkOjpjb3V0IDw8IHBjaC50b3AoKTsKCQlwY2gucG9wKCk7Cgl9CglzdGQ6OmNvdXQgPDwgc3RkOjplbmRsOwoKCS8vLi4uCgoJaW50IEFbXSA9IHsgNSwgMiwgOCwgNiwgNywgMSwgOSwgMywgMCwgNCB9OwoJcHF1ZXVlPGludCwgaW50Y21wPiBwcShBLCBBICsgc2l6ZW9mKEEpL3NpemVvZihBWzBdKSk7CgoJd2hpbGUoISBwcS5lbXB0eSgpKXsKCQlzdGQ6OmNvdXQgPDwgcHEudG9wKCkgPDwgJyAnOwoJCXBxLnBvcCgpOwoJfQoJcmV0dXJuIDA7Cn0=