Fibonacci堆的代码-欢迎斧正并且报告Bug

#include"stdafx.h"
#include
#include
#include"PriorityQueue.h"
#include
#include
#include
using namespace std;

//Node: 
  //Pointer: Left, Right, Parent, Child 
  //bool mark, ElemType elem, int degree
class Node {
public:
	Node();
	Node(ElemType elem);
	Node *left, *right, *parent, *child;
	bool mark;
	ElemType elem;
	int degree;
};



//FibonacciHeap
  //Size
  //Pointer: rootlist, min
class FibHeap {
public:
	FibHeap();
	void Insert(ElemType elem);
	void Insert(Node *t);
	Node* ExtractMin();
	void DecreaseKey(Node *e, int key);
	void FibHeapDelete(Node *e);
	set FibHeapNodes;
	vectorFibHeapNodesVector; //For delete
	~FibHeap();

protected:
	void Consolidate();
	void Cut(Node *cutnode, Node *parent);
	void CascadingCut(Node *node);
	int MaxDegree(); //Return the max degree of node in the FibHeap
	void FibLink(Node *y, Node *x);
private:
	Node* rootlist;
	Node* min;
	int size;
};


void TestFib();
int main() {
	//freopen("input.txt", "r", stdin);
	TestFib();
	int i = 0; 
	cin>>i;
}

/* 1 2 1 3 1 4 1 5 2  2 2 */
void TestFib() {
	FibHeap *fib = new FibHeap();
	int i;
	ElemType elem;
	Node *ret = 0;
	set::reverse_iterator it;
	while(true) {
		cin>>i;
		switch(i) {
		case 1:
			//Insert
			cin>>elem.key;
			fib->Insert(elem);
			break;
		case 2:
			//ExtractMin
			ret = fib->ExtractMin();
			if(ret == 0) cout<<"error"<elem.key<FibHeapNodes.rbegin(); it != fib->FibHeapNodes.rend(); it++) {
				fib->DecreaseKey(*it, (*it)->elem.key - 1);
			}
			break;
		case 4:
			break;
		case 5:
			delete fib;
			return;
		}
		
	}
}

Node::Node() { //这段重复代码如何去除
	left = right = parent = child = 0;
	mark = false;
	degree = 0;
}
Node::Node(ElemType elem) {
	this->elem = elem;
	left = right = parent = child = 0;
	mark = false;
	degree = 0;
}

FibHeap::FibHeap(){
	this->min = this->rootlist = 0;
	this->size = 0;
}
void FibHeap::Insert(ElemType elem) {
	Node *e = new Node(elem);
	Insert(e);
}
void FibHeap::Insert(Node *t) {
	FibHeapNodes.insert(t);
	t->left = t->right = t;
	if(rootlist == 0) {
		this->min = this->rootlist = t;
	} else{
		t->right = rootlist;
		t->left = rootlist->left;
		t->left->right = t->right->left = t;		
		if(Less(t->elem, this->min->elem)) this->min = t;
	}
	this->size++;
}
Node *FibHeap::ExtractMin() {
	Node* ret = this->min;
	//Add all the child of this->min to the rootlist of Heap
	if(ret == 0) return 0;
	if(ret->child != 0) {
		//Add all the child of this->min to the rootlist
		//at this time, rootlist != NIL
		Node *prev = ret->child, *next;
		do {
			//Add the node of prev to the rootlist
			next = prev->right;

			prev->right = rootlist;
			prev->left = rootlist->left;
			prev->left->right = prev->right->left = prev;
			rootlist = prev; //rootlist可改可不改
			prev->parent = 0;

			prev = next;
		} while(next != ret->child);
	}
	//Remove this->min
	ret->right->left = ret->left;
	ret->left->right = ret->right;
	if(rootlist == ret) rootlist = ret->right;
	if(ret == ret->right)this->rootlist =  this->min = 0;
	else {
		this->min = ret->right;
		Consolidate();
	}
	//Consolidate the FibHeap
	this->size--;
	FibHeapNodes.erase(ret);
	return ret;
}

void FibHeap::Consolidate() {
	int maxDegree = this->MaxDegree();
	//数组一定要初始化
	Node **aux = new Node* [maxDegree + 1]; //Auxiliary Array< aux[d]: tree with degree d>
	for(int i = 0; i <= maxDegree; i++) aux[i] = 0;
	//Iterate over the rootlist
	Node *iter = rootlist, *next;
	if(iter == 0) return;//It means the list is empty
	do {
		Node *x = iter; //FibLink Will change Iter
		int degree = x->degree;
		next = iter->right;
		while(aux[degree] != 0) {
			Node *y = aux[degree];
			if(Less(y->elem, x->elem)) {
				//SWAP X AND Y 可以考虑用宏实现
				Node *temp = x;
				x = y; 
				y = temp;
			}
			FibLink(y, x); //Let y be a child of x //此处改变了next->right
			aux[degree] = 0;
			degree++;
		}
		aux[degree] = x;
		iter = next; //iter can't be zero
	}while(iter != rootlist);
	//Reconstruct the list
	this->min = this->rootlist = 0;
	for(int i = 0; i <= maxDegree; i++) { //Add the list to the rootlist
		if(aux[i] != 0) { //代码可以更加简洁
			if(rootlist == 0){
				this->min = this->rootlist = aux[i]->left = aux[i]->right = aux[i]; // When rootlist is empty
			}
			else {
				//Add aux[i];
				aux[i]->right = rootlist;
				aux[i]->left = rootlist->left;
				aux[i]->left->right = aux[i]->right->left = aux[i];
				if(Less(aux[i]->elem, this->min->elem)) this->min = aux[i];
			}
		}
	}
	delete[] aux;
}

void FibHeap::FibLink(Node *y, Node *x) {
	//Remove y from the rootlist, may no need 这一个决定删去,因为会影响正确性
	//y->left->right = y->right;//这一段话导致了next值出错 if y is the rootlist
	//y->right->left =  y->left;
	//if(y == rootlist) rootlist = y->right; 加上这一句话也未必是对的

	//Make y a child of x, add the degree of x 双向链表的表头。 对指针的引用存在不?
	y->parent = x;
	if(x->child == 0) x->child = y->left = y->right = y;
	else {
		y->left = x->child->left;
		y->right = x->child;
		y->left->right = y->right->left = y;
	}
	x->degree++;
	//Mark y = false why? y的度已经改变了。然后重新加入到rootlist中的,所以mark可以为负值
	y->mark = false; 
}
void FibHeap::DecreaseKey(Node *e, int key) {
	if(e == 0) return;
	if(e->elem.key <= key) return;
	e->elem.key = key;
	Node *p = e->parent;
	if(p != 0 && Less(e->elem, p->elem)) {
		Cut(e, p);
		CascadingCut(p);
	}
	if(Less(e->elem, this->min->elem)) this->min = e;
}

void FibHeap::Cut(Node *cutNode, Node *parent) { 
	//Remove cutNode from parent list
	if(parent->child == cutNode) {
		if(parent->degree == 1) //Only one child
			parent->child = 0;
		else
			parent->child = cutNode->right;
	}
	cutNode->right->left = cutNode->left;
	cutNode->left->right = cutNode->right;
	parent->degree--;
	
	//Add cutNode to the rootlist 
	//rootlist can't be empty!
	cutNode->right = rootlist;
	cutNode->left = rootlist->left;
	cutNode->left->right = cutNode->right->left = cutNode;
	
	//Pointer:mark parent
	cutNode->mark = false; //?? why?? 还是无法理解mark商标
	cutNode->parent = 0;
}
void FibHeap::CascadingCut(Node *node) {
	Node *parent = node->parent;
	if(parent != 0) 
		if(parent->mark == false) parent->mark = true;
		else{
			Cut(node, parent);
			CascadingCut(parent);
		}
}

void FibHeap::FibHeapDelete(Node *e) {
	this->DecreaseKey(e, -9999);
	free(this->ExtractMin());
}

int FibHeap::MaxDegree() {
	if(this->size == 0) return 0;
	int max = (int) (2 * log((float)this->size) / log((float)2)) + 2;
	return max;
} 

FibHeap::~FibHeap() {
	set::iterator it;
	for(it = FibHeapNodes.begin(); it != FibHeapNodes.end(); it++) FibHeapNodesVector.push_back(*it);
	for(int i = 0; i < FibHeapNodesVector.size(); i++) {
		cout<<"Clearing: "<elem.key<


你可能感兴趣的:(算法,insert,less,iterator,delete,float,list)