Pagini recente » Cod sursa (job #2819277) | Cod sursa (job #189408) | Cod sursa (job #190113) | Cod sursa (job #1778335) | Cod sursa (job #3124082)
#include <list>
#include <ostream>
#include <fstream>
class BinomialHeap {
public:
struct Node {
long long value, degree;
Node *child, *sibling, *parent;
};
private:
std::list <Node*> roots;
public:
void print(std::ostream&) const;
static void printTree(std::ostream&, Node*);
static Node* newNode(long long value);
static Node* mergeTrees(Node*, Node*);
void insertTree(Node*);
void unionHeap(std::list <Node*>);
void unionHeap(const BinomialHeap& );
void addValue(long long);
long long getMin() const;
void deleteMin();
bool empty() const;
};
void BinomialHeap::print(std::ostream &out) const{
for(auto& it: this->roots) {
BinomialHeap::printTree(out, it);
}
}
void BinomialHeap::printTree(std::ostream &out, Node *node) {
out << node->value << " " << node->degree << '\n';
Node *it = node->child;
while(it != nullptr) {
BinomialHeap::printTree(out, it);
it = it->sibling;
}
}
BinomialHeap::Node *BinomialHeap::newNode(long long value) {
Node *temp = new Node;
temp->value = value;
temp->degree = 0;
temp->child = nullptr;
temp->sibling = nullptr;
temp->parent = nullptr;
return temp;
}
BinomialHeap::Node *BinomialHeap::mergeTrees(BinomialHeap::Node *a, BinomialHeap::Node *b) {
if(a->value < b->value) {
std::swap(a, b);
}
a->sibling = b->child;
a->parent = b;
b->child = a;
b->degree ++;
return b;
}
void BinomialHeap::unionHeap(std::list<Node *> heap) {
std::list <Node*> temp;
std::list<Node*>::iterator i;
std::list<Node*>::iterator j;
i = this->roots.begin();
j = heap.begin();
Node* carry = nullptr;
while(i != this->roots.end() and j != heap.end()){
if(carry != nullptr) {
if((*i)->degree == (*j)->degree and carry->degree) {
temp.push_back(carry);
carry = nullptr;
}
else if((*i)->degree == carry->degree) {
carry = BinomialHeap::mergeTrees(*i, carry);
i ++;
}
else if((*j)->degree == carry->degree) {
carry = BinomialHeap::mergeTrees(*j, carry);
j ++;
}
else {
temp.push_back(carry);
carry = nullptr;
}
}
if((*i)->degree == (*j)->degree) {
carry = BinomialHeap::mergeTrees(*i, *j);
i ++;
j ++;
}
else if((*i)->degree < (*j)->degree) {
temp.push_back(*i);
i ++;
}
else {
temp.push_back(*j);
j ++;
}
}
while(i != this->roots.end()) {
if(carry != nullptr and (*i)->degree == carry->degree) {
carry = BinomialHeap::mergeTrees(*i, carry);
i ++;
}
else if(carry != nullptr) {
temp.push_back(carry);
carry = nullptr;
}
else {
temp.push_back(*i);
i ++;
}
}
while(j != heap.end()) {
if(carry != nullptr and (*j)->degree == carry->degree) {
carry = BinomialHeap::mergeTrees(*j, carry);
j ++;
}
else if(carry != nullptr) {
temp.push_back(carry);
carry = nullptr;
}
else {
temp.push_back(*j);
j ++;
}
}
if(carry != nullptr) {
temp.push_back(carry);
carry = nullptr;
}
this->roots = temp;
}
void BinomialHeap::insertTree(BinomialHeap::Node *node) {
std::list <Node*> temp;
temp.push_back(node);
this->unionHeap(temp);
}
void BinomialHeap::addValue(long long value) {
this->insertTree(BinomialHeap::newNode(value));
}
long long BinomialHeap::getMin() const {
long long temp = INT64_MAX;
for(auto& it: this->roots) {
temp = std::min(temp, it->value);
}
return temp;
}
void BinomialHeap::deleteMin() {
std::list <Node*> temp;
long long min = this->getMin();
Node* node = nullptr;
for(auto& it: this->roots) {
if(it->value == min) {
node = it;
this->roots.remove(it);
break;
}
}
if(node == nullptr) {
return;
}
Node *it = node->child;
while(it != nullptr) {
temp.push_back(it);
it = it->sibling;
}
this->unionHeap(temp);
}
bool BinomialHeap::empty() const {
return this->roots.empty();
}
void BinomialHeap::unionHeap(const BinomialHeap& heap) {
this->unionHeap(heap.roots);
}
int main() {
std::ifstream fin("algsort.in");
std::ofstream fout("algsort.out");
BinomialHeap heap;
int n;
fin >> n;
for(int i = 0; i < n; i ++) {
int temp;
fin >> temp;
heap.addValue(temp);
}
while(!heap.empty()) {
fout << heap.getMin() << ' ';
heap.deleteMin();
}
return 0;
}