求助,斐波那契堆,求复杂度
查看原帖
求助,斐波那契堆,求复杂度
1074696
tmlrock楼主2023/9/15 22:21
#include<bits/stdc++.h>
using namespace std;
template<typename T>
class FibHeap {
	private:
		struct node {
			T data;
			bool mark;
			int degree;
			node *left, *right;
			node *child, *parent;
			node() {
				mark = false;
				degree = 0;
				child = parent = nullptr;
				left = right = this;
			}
		};
		unsigned size;
		node *min;
		node *head;
		T MIN_VALUE;
		void LeftInsert(node *base, node *tmp) {
			tmp->left = base->left;
			tmp->right = base;
			base->left->right = tmp;
			base->left = tmp;
		}
		void link(node *y, node *x) {
			y->left->right = y->right;
			y->right->left = y->left;
			y->parent = x;
			if (x->child == nullptr) {
				x->child = y;
				y->left = y->right = y;
			} else LeftInsert(x->child, y);
			x->degree++;
			y->mark = false;
		}
		void Consolidate() {
			int Dn = (int)log2(size) + 1;
			node **nodes = new node*[Dn];
			for (int i = 0; i < Dn; i++)
				nodes[i] = nullptr;
			node *ptr = head->right, *nxt;
			do {
				int d;
				node *x, *y;
				x = ptr;
				if (x == head) continue;
				d = x->degree;
				nxt = ptr->right;
				while (nodes[d] != nullptr) {
					y = nodes[d];
					if (x->data > y->data)
						std::swap(x, y);
					link(y, x);
					nodes[d] = nullptr;
					d++;
				}
				nodes[d] = x;
				ptr = nxt;
			} while (ptr != head);
			min = nullptr;
			head->left = head->right = head;
			for (int i = 0; i < Dn; i++) {
				if (nodes[i] != nullptr) {
					if (min == nullptr) {
						min = nodes[i];
						LeftInsert(head, min);
					} else {
						LeftInsert(head, nodes[i]);
						if (nodes[i]->data < min->data)
							min = nodes[i];
					}
				}
			}
		}
	public:
		FibHeap() {
			size = 0;
			min = nullptr;
			head = new node;
		}
		FibHeap(T MIN_VALUE) {
			size = 0;
			min = nullptr;
			head = new node;
			this->MIN_VALUE = MIN_VALUE;
		}
		T GetMin() {
			return min->data;
		}
		int Size() {
			return size;
		}

		void Insert(node *data) {
			if (min == nullptr) {
				min = data;
				LeftInsert(head, min);
			} else {
				LeftInsert(min, data);
				if (data->data < min->data) {
					min = data;
				}
			}
			size++;
		}
		void Insert_(T data) {
			//初始化
			node *tmp = new node;
			tmp->degree = 0;
			tmp->data = data;
			tmp->parent = tmp->child = nullptr;
			tmp->left = tmp->right = tmp;//双向循环链表需要把左右指针指向自己
			tmp->mark = false;
			if (min == nullptr) { //空堆,min指针指向该结点
				min = tmp;
				LeftInsert(head, min);//LeftInsert定义见上方
			} else {
				LeftInsert(min, tmp);
				if (data < min->data) //插入的结点更小,min指向新结点
					min = tmp;
			}
			size++;
		}
		FibHeap<T> Merge(FibHeap<T> H2) {
			node *ptr = head->right;
			do {
				node *rb = ptr->right;
				H2.Insert(ptr);
				ptr = rb;
			} while (ptr != head);
			if (H2.min == nullptr || (min != nullptr && min->data < H2.GetMin()))
				H2.min = min;
			return H2;
		}
		T DeleteMin() {
			T ret = min->data;
			node *ptr = min;
			if (ptr != nullptr) {
				node *tmp = min->child, *nxt;
				for (int i = 0; i < min->degree; i++) {
					nxt = tmp->right;
					LeftInsert(head, tmp);
					tmp = nxt;
				}
				ptr->left->right = ptr->right;
				ptr->right->left = ptr->left;

				if (ptr == ptr->right)
					min = nullptr;
				else {
					min = min->right;
					if (min == head) min = min->right;
					Consolidate();
				}
				size--;
			}
			return ret;
		}
		void Cut(node *x, node *y) {
			if (y->degree == 1)
				y->child = nullptr;
			else {
				x->left->right = x->right;
				x->right->left = x->left;
			}
			y->degree--;
			LeftInsert(head, x);
			x->parent = nullptr;
			x->mark = false;
		}
		void CascadingCut(node *y) {
			node *z = y->parent;
			if (z != nullptr) {
				if (y->mark == false)
					y->mark = true;
				else {
					Cut(y, z);
					CascadingCut(z);
				}
			}
		}
		void DecreaseKey(node *x, T key) {
			if (key >= x->data) return;
			x->data = key;

			node *y = x->parent;
			if (y != nullptr && x->data < y->data) {
				Cut(x, y);
				CascadingCut(y);
			}
			if (x->data < min->data)
				min = x;
		}
		void Delete(node *x) {
			DecreaseKey(x, MIN_VALUE);
			DeleteMin();
		}
};
const int inf = 0x3f3f3f3f;
FibHeap<pair<int, int> > heap;
int a[100010];
int n;
int main() {
	cin>>n;
	for(int i = 1;i<=n;++i)cin>>a[i] , heap.Insert_(make_pair(a[i],i)) ;
	for(int i = 1;i<=n;++i) {
		int min_idx = heap.GetMin().second;
		cout<<a[min_idx]<<' ';
		heap.DeleteMin();
	}
//	for(int i = 1;i<=n;++i)cout<<a[i]<<" \n"[i==n];
}

2023/9/15 22:21
加载中...