原文: https://www.programiz.com/dsa/decrease-key-and-delete-node-from-a-fibonacci-heap

在本教程中,您将学习减小键和删除节点操作的工作方式。 此外,您还将在 C,C++ ,Java 和 Python 的斐波那契堆上找到这些操作的工作示例。

在斐波那契堆中,减小键和删除节点是重要的操作。 这些操作将在下面讨论。


减小键

在减小键操作中,键的值被减小到较低的值。

以下函数用于减小键。

减小键

  1. 选择要减小的节点x,并将其值更改为新值k
  2. 如果x的父级y不为空,并且父级的键大于k的键,则调用C ut(x)C ascading- C ut(y)随后。
  3. 如果x的键小于min的键,则将x标记为min

剪裁

  1. 从当前位置删除x并将其添加到根列表中。
  2. 如果标记了x,则将其标记为false

级联剪裁

  1. 如果y的父级不为空,请执行以下步骤。
  2. 如果未标记y,则标记y
  3. 否则,调用Cut(y)Cascading-Cut(parent of y)

减小键示例

在以下示例中可以理解上述操作。

示例:将 46 减小到 15。

  1. 将值减小 46 到 15。

  2. 剪裁部分:由于24 ≠ nill15 < its parent,将其剪裁并将其添加到根列表中。 级联剪裁部分:标记为 24。
    减小斐波那契堆上的键和删除节点的操作 - 图1
    在根列表中添加 15 并标记为 24

示例:将 35 减小到 5

  1. 将值减小 35 到 5。
    减小斐波那契堆上的键和删除节点的操作 - 图2
    将值 35 减小到 5

  2. 剪裁部分:由于26 ≠ nill5<its parent,将其剪裁并将其添加到根列表中。
    减小斐波那契堆上的键和删除节点的操作 - 图3
    剪裁 5 并将其添加到根列表

  3. 级联剪裁部分:由于标记为 26,因此流程进入CutCascading-Cut
    Cut(26):剪裁 26 并将其添加到根列表中,并将其标记为false
    减小斐波那契堆上的键和删除节点的操作 - 图4
    剪裁 26 并将其添加到根列表中。 调用Cut(24)Cascading-Cut(7)。 这些操作将导致下面的树。
    减小斐波那契堆上的键和删除节点的操作 - 图5
    削减 24 并将其添加到根列表中

  4. 5 < 7开始,将 5 标记为分钟。
    减小斐波那契堆上的键和删除节点的操作 - 图6
    将 5 标记为最小值


删除节点

此过程使用减小键最小提取操作。 请按照以下步骤删除节点。

  1. k为要删除的节点。
  2. 应用减小键操作将k的值减小到可能的最低值(即-∞)。
  3. 应用extract-min操作删除该节点。

Python,Java 和 C/C++ 示例

  1. # Fibonacci Heap in python
  2. import math
  3. class FibonacciTree:
  4. def __init__(self, key):
  5. self.key = key
  6. self.children = []
  7. self.order = 0
  8. def add_at_end(self, t):
  9. self.children.append(t)
  10. self.order = self.order + 1
  11. class FibonacciHeap:
  12. def __init__(self):
  13. self.trees = []
  14. self.least = None
  15. self.count = 0
  16. def insert(self, key):
  17. new_tree = FibonacciTree(key)
  18. self.trees.append(new_tree)
  19. if (self.least is None or key < self.least.key):
  20. self.least = new_tree
  21. self.count = self.count + 1
  22. def get_min(self):
  23. if self.least is None:
  24. return None
  25. return self.least.key
  26. def extract_min(self):
  27. smallest = self.least
  28. if smallest is not None:
  29. for child in smallest.children:
  30. self.trees.append(child)
  31. self.trees.remove(smallest)
  32. if self.trees == []:
  33. self.least = None
  34. else:
  35. self.least = self.trees[0]
  36. self.consolidate()
  37. self.count = self.count - 1
  38. return smallest.key
  39. def consolidate(self):
  40. aux = (floor_log2(self.count) + 1) * [None]
  41. while self.trees != []:
  42. x = self.trees[0]
  43. order = x.order
  44. self.trees.remove(x)
  45. while aux[order] is not None:
  46. y = aux[order]
  47. if x.key > y.key:
  48. x, y = y, x
  49. x.add_at_end(y)
  50. aux[order] = None
  51. order = order + 1
  52. aux[order] = x
  53. self.least = None
  54. for k in aux:
  55. if k is not None:
  56. self.trees.append(k)
  57. if (self.least is None
  58. or k.key < self.least.key):
  59. self.least = k
  60. def floor_log2(x):
  61. return math.frexp(x)[1] - 1
  62. fheap = FibonacciHeap()
  63. fheap.insert(11)
  64. fheap.insert(10)
  65. fheap.insert(39)
  66. fheap.insert(26)
  67. fheap.insert(24)
  68. print('Minimum value: {}'.format(fheap.get_min()))
  69. print('Minimum value removed: {}'.format(fheap.extract_min()))
  1. // Operations on Fibonacci Heap in Java
  2. class node {
  3. node parent;
  4. node left;
  5. node right;
  6. node child;
  7. int degree;
  8. boolean mark;
  9. int key;
  10. public node() {
  11. this.degree = 0;
  12. this.mark = false;
  13. this.parent = null;
  14. this.left = this;
  15. this.right = this;
  16. this.child = null;
  17. this.key = Integer.MAX_VALUE;
  18. }
  19. node(int x) {
  20. this();
  21. this.key = x;
  22. }
  23. void set_parent(node x) {
  24. this.parent = x;
  25. }
  26. node get_parent() {
  27. return this.parent;
  28. }
  29. void set_left(node x) {
  30. this.left = x;
  31. }
  32. node get_left() {
  33. return this.left;
  34. }
  35. void set_right(node x) {
  36. this.right = x;
  37. }
  38. node get_right() {
  39. return this.right;
  40. }
  41. void set_child(node x) {
  42. this.child = x;
  43. }
  44. node get_child() {
  45. return this.child;
  46. }
  47. void set_degree(int x) {
  48. this.degree = x;
  49. }
  50. int get_degree() {
  51. return this.degree;
  52. }
  53. void set_mark(boolean m) {
  54. this.mark = m;
  55. }
  56. boolean get_mark() {
  57. return this.mark;
  58. }
  59. void set_key(int x) {
  60. this.key = x;
  61. }
  62. int get_key() {
  63. return this.key;
  64. }
  65. }
  66. public class fibHeap {
  67. node min;
  68. int n;
  69. boolean trace;
  70. node found;
  71. public boolean get_trace() {
  72. return trace;
  73. }
  74. public void set_trace(boolean t) {
  75. this.trace = t;
  76. }
  77. public static fibHeap create_heap() {
  78. return new fibHeap();
  79. }
  80. fibHeap() {
  81. min = null;
  82. n = 0;
  83. trace = false;
  84. }
  85. private void insert(node x) {
  86. if (min == null) {
  87. min = x;
  88. x.set_left(min);
  89. x.set_right(min);
  90. } else {
  91. x.set_right(min);
  92. x.set_left(min.get_left());
  93. min.get_left().set_right(x);
  94. min.set_left(x);
  95. if (x.get_key() < min.get_key())
  96. min = x;
  97. }
  98. n += 1;
  99. }
  100. public void insert(int key) {
  101. insert(new node(key));
  102. }
  103. public void display() {
  104. display(min);
  105. System.out.println();
  106. }
  107. private void display(node c) {
  108. System.out.print("(");
  109. if (c == null) {
  110. System.out.print(")");
  111. return;
  112. } else {
  113. node temp = c;
  114. do {
  115. System.out.print(temp.get_key());
  116. node k = temp.get_child();
  117. display(k);
  118. System.out.print("->");
  119. temp = temp.get_right();
  120. } while (temp != c);
  121. System.out.print(")");
  122. }
  123. }
  124. public static void merge_heap(fibHeap H1, fibHeap H2, fibHeap H3) {
  125. H3.min = H1.min;
  126. if (H1.min != null && H2.min != null) {
  127. node t1 = H1.min.get_left();
  128. node t2 = H2.min.get_left();
  129. H1.min.set_left(t2);
  130. t1.set_right(H2.min);
  131. H2.min.set_left(t1);
  132. t2.set_right(H1.min);
  133. }
  134. if (H1.min == null || (H2.min != null && H2.min.get_key() < H1.min.get_key()))
  135. H3.min = H2.min;
  136. H3.n = H1.n + H2.n;
  137. }
  138. public int find_min() {
  139. return this.min.get_key();
  140. }
  141. private void display_node(node z) {
  142. System.out.println("right: " + ((z.get_right() == null) ? "-1" : z.get_right().get_key()));
  143. System.out.println("left: " + ((z.get_left() == null) ? "-1" : z.get_left().get_key()));
  144. System.out.println("child: " + ((z.get_child() == null) ? "-1" : z.get_child().get_key()));
  145. System.out.println("degree " + z.get_degree());
  146. }
  147. public int extract_min() {
  148. node z = this.min;
  149. if (z != null) {
  150. node c = z.get_child();
  151. node k = c, p;
  152. if (c != null) {
  153. do {
  154. p = c.get_right();
  155. insert(c);
  156. c.set_parent(null);
  157. c = p;
  158. } while (c != null && c != k);
  159. }
  160. z.get_left().set_right(z.get_right());
  161. z.get_right().set_left(z.get_left());
  162. z.set_child(null);
  163. if (z == z.get_right())
  164. this.min = null;
  165. else {
  166. this.min = z.get_right();
  167. this.consolidate();
  168. }
  169. this.n -= 1;
  170. return z.get_key();
  171. }
  172. return Integer.MAX_VALUE;
  173. }
  174. public void consolidate() {
  175. double phi = (1 + Math.sqrt(5)) / 2;
  176. int Dofn = (int) (Math.log(this.n) / Math.log(phi));
  177. node[] A = new node[Dofn + 1];
  178. for (int i = 0; i <= Dofn; ++i)
  179. A[i] = null;
  180. node w = min;
  181. if (w != null) {
  182. node check = min;
  183. do {
  184. node x = w;
  185. int d = x.get_degree();
  186. while (A[d] != null) {
  187. node y = A[d];
  188. if (x.get_key() > y.get_key()) {
  189. node temp = x;
  190. x = y;
  191. y = temp;
  192. w = x;
  193. }
  194. fib_heap_link(y, x);
  195. check = x;
  196. A[d] = null;
  197. d += 1;
  198. }
  199. A[d] = x;
  200. w = w.get_right();
  201. } while (w != null && w != check);
  202. this.min = null;
  203. for (int i = 0; i <= Dofn; ++i) {
  204. if (A[i] != null) {
  205. insert(A[i]);
  206. }
  207. }
  208. }
  209. }
  210. private void fib_heap_link(node y, node x) {
  211. y.get_left().set_right(y.get_right());
  212. y.get_right().set_left(y.get_left());
  213. node p = x.get_child();
  214. if (p == null) {
  215. y.set_right(y);
  216. y.set_left(y);
  217. } else {
  218. y.set_right(p);
  219. y.set_left(p.get_left());
  220. p.get_left().set_right(y);
  221. p.set_left(y);
  222. }
  223. y.set_parent(x);
  224. x.set_child(y);
  225. x.set_degree(x.get_degree() + 1);
  226. y.set_mark(false);
  227. }
  228. private void find(int key, node c) {
  229. if (found != null || c == null)
  230. return;
  231. else {
  232. node temp = c;
  233. do {
  234. if (key == temp.get_key())
  235. found = temp;
  236. else {
  237. node k = temp.get_child();
  238. find(key, k);
  239. temp = temp.get_right();
  240. }
  241. } while (temp != c && found == null);
  242. }
  243. }
  244. public node find(int k) {
  245. found = null;
  246. find(k, this.min);
  247. return found;
  248. }
  249. public void decrease_key(int key, int nval) {
  250. node x = find(key);
  251. decrease_key(x, nval);
  252. }
  253. private void decrease_key(node x, int k) {
  254. if (k > x.get_key())
  255. return;
  256. x.set_key(k);
  257. node y = x.get_parent();
  258. if (y != null && x.get_key() < y.get_key()) {
  259. cut(x, y);
  260. cascading_cut(y);
  261. }
  262. if (x.get_key() < min.get_key())
  263. min = x;
  264. }
  265. private void cut(node x, node y) {
  266. x.get_right().set_left(x.get_left());
  267. x.get_left().set_right(x.get_right());
  268. y.set_degree(y.get_degree() - 1);
  269. x.set_right(null);
  270. x.set_left(null);
  271. insert(x);
  272. x.set_parent(null);
  273. x.set_mark(false);
  274. }
  275. private void cascading_cut(node y) {
  276. node z = y.get_parent();
  277. if (z != null) {
  278. if (y.get_mark() == false)
  279. y.set_mark(true);
  280. else {
  281. cut(y, z);
  282. cascading_cut(z);
  283. }
  284. }
  285. }
  286. public void delete(node x) {
  287. decrease_key(x, Integer.MIN_VALUE);
  288. int p = extract_min();
  289. }
  290. public static void main(String[] args) {
  291. fibHeap obj = create_heap();
  292. obj.insert(7);
  293. obj.insert(26);
  294. obj.insert(30);
  295. obj.insert(39);
  296. obj.insert(10);
  297. obj.display();
  298. System.out.println(obj.extract_min());
  299. obj.display();
  300. System.out.println(obj.extract_min());
  301. obj.display();
  302. System.out.println(obj.extract_min());
  303. obj.display();
  304. System.out.println(obj.extract_min());
  305. obj.display();
  306. System.out.println(obj.extract_min());
  307. obj.display();
  308. }
  309. }
// Operations on a Fibonacci heap in C

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <math.h>

typedef struct _NODE
{
  int key;
  int degree;
  struct _NODE *left_sibling;
  struct _NODE *right_sibling;
  struct _NODE *parent;
  struct _NODE *child;
  bool mark;
  bool visited;
} NODE;

typedef struct fibanocci_heap
{
  int n;
  NODE *min;
  int phi;
  int degree;
} FIB_HEAP;

FIB_HEAP *make_fib_heap();
void insertion(FIB_HEAP *H, NODE *new, int val);
NODE *extract_min(FIB_HEAP *H);
void consolidate(FIB_HEAP *H);
void fib_heap_link(FIB_HEAP *H, NODE *y, NODE *x);
NODE *find_min_node(FIB_HEAP *H);
void decrease_key(FIB_HEAP *H, NODE *node, int key);
void cut(FIB_HEAP *H, NODE *node_to_be_decrease, NODE *parent_node);
void cascading_cut(FIB_HEAP *H, NODE *parent_node);
void Delete_Node(FIB_HEAP *H, int dec_key);

FIB_HEAP *make_fib_heap()
{
  FIB_HEAP *H;
  H = (FIB_HEAP *)malloc(sizeof(FIB_HEAP));
  H->n = 0;
  H->min = NULL;
  H->phi = 0;
  H->degree = 0;
  return H;
}
void new_print_heap(NODE *n)
{
  NODE *x;
  for (x = n;; x = x->right_sibling)
  {

    if (x->child == NULL)
    {
      printf("node with no child (%d) \n", x->key);
    }
    else
    {

      printf("NODE(%d) with child (%d)\n", x->key, x->child->key);
      new_print_heap(x->child);
    }
    if (x->right_sibling == n)
    {
      break;
    }
  }
}

void insertion(FIB_HEAP *H, NODE *new, int val)
{
  new = (NODE *)malloc(sizeof(NODE));
  new->key = val;
  new->degree = 0;
  new->mark = false;
  new->parent = NULL;
  new->child = NULL;
  new->visited = false;
  new->left_sibling = new;
  new->right_sibling = new;
  if (H->min == NULL)
  {
    H->min = new;
  }
  else
  {
    H->min->left_sibling->right_sibling = new;
    new->right_sibling = H->min;
    new->left_sibling = H->min->left_sibling;
    H->min->left_sibling = new;
    if (new->key < H->min->key)
    {
      H->min = new;
    }
  }
  (H->n)++;
}

NODE *find_min_node(FIB_HEAP *H)
{
  if (H == NULL)
  {
    printf(" \n Fibonacci heap not yet created \n");
    return NULL;
  }
  else
    return H->min;
}

FIB_HEAP *unionHeap(FIB_HEAP *H1, FIB_HEAP *H2)
{
  FIB_HEAP *Hnew;
  Hnew = make_fib_heap();
  Hnew->min = H1->min;

  NODE *temp1, *temp2;
  temp1 = Hnew->min->right_sibling;
  temp2 = H2->min->left_sibling;

  Hnew->min->right_sibling->left_sibling = H2->min->left_sibling;
  Hnew->min->right_sibling = H2->min;
  H2->min->left_sibling = Hnew->min;
  temp2->right_sibling = temp1;

  if ((H1->min == NULL) || (H2->min != NULL && H2->min->key < H1->min->key))
    Hnew->min = H2->min;
  Hnew->n = H1->n + H2->n;
  return Hnew;
}

int cal_degree(int n)
{
  int count = 0;
  while (n > 0)
  {
    n = n / 2;
    count++;
  }
  return count;
}
void consolidate(FIB_HEAP *H)
{
  int degree, i, d;
  degree = cal_degree(H->n);
  NODE *A[degree], *x, *y, *z;
  for (i = 0; i <= degree; i++)
  {
    A[i] = NULL;
  }
  x = H->min;
  do
  {
    d = x->degree;
    while (A[d] != NULL)
    {
      y = A[d];
      if (x->key > y->key)
      {
        NODE *exchange_help;
        exchange_help = x;
        x = y;
        y = exchange_help;
      }
      if (y == H->min)
        H->min = x;
      fib_heap_link(H, y, x);
      if (y->right_sibling == x)
        H->min = x;
      A[d] = NULL;
      d++;
    }
    A[d] = x;
    x = x->right_sibling;
  } while (x != H->min);

  H->min = NULL;
  for (i = 0; i < degree; i++)
  {
    if (A[i] != NULL)
    {
      A[i]->left_sibling = A[i];
      A[i]->right_sibling = A[i];
      if (H->min == NULL)
      {
        H->min = A[i];
      }
      else
      {
        H->min->left_sibling->right_sibling = A[i];
        A[i]->right_sibling = H->min;
        A[i]->left_sibling = H->min->left_sibling;
        H->min->left_sibling = A[i];
        if (A[i]->key < H->min->key)
        {
          H->min = A[i];
        }
      }
      if (H->min == NULL)
      {
        H->min = A[i];
      }
      else if (A[i]->key < H->min->key)
      {
        H->min = A[i];
      }
    }
  }
}

void fib_heap_link(FIB_HEAP *H, NODE *y, NODE *x)
{
  y->right_sibling->left_sibling = y->left_sibling;
  y->left_sibling->right_sibling = y->right_sibling;

  if (x->right_sibling == x)
    H->min = x;

  y->left_sibling = y;
  y->right_sibling = y;
  y->parent = x;

  if (x->child == NULL)
  {
    x->child = y;
  }
  y->right_sibling = x->child;
  y->left_sibling = x->child->left_sibling;
  x->child->left_sibling->right_sibling = y;
  x->child->left_sibling = y;
  if ((y->key) < (x->child->key))
    x->child = y;

  (x->degree)++;
}
NODE *extract_min(FIB_HEAP *H)
{

  if (H->min == NULL)
    printf("\n The heap is empty");
  else
  {
    NODE *temp = H->min;
    NODE *pntr;
    pntr = temp;
    NODE *x = NULL;
    if (temp->child != NULL)
    {

      x = temp->child;
      do
      {
        pntr = x->right_sibling;
        (H->min->left_sibling)->right_sibling = x;
        x->right_sibling = H->min;
        x->left_sibling = H->min->left_sibling;
        H->min->left_sibling = x;
        if (x->key < H->min->key)
          H->min = x;
        x->parent = NULL;
        x = pntr;
      } while (pntr != temp->child);
    }

    (temp->left_sibling)->right_sibling = temp->right_sibling;
    (temp->right_sibling)->left_sibling = temp->left_sibling;
    H->min = temp->right_sibling;

    if (temp == temp->right_sibling && temp->child == NULL)
      H->min = NULL;
    else
    {
      H->min = temp->right_sibling;
      consolidate(H);
    }
    H->n = H->n - 1;
    return temp;
  }
  return H->min;
}

void cut(FIB_HEAP *H, NODE *node_to_be_decrease, NODE *parent_node)
{
  NODE *temp_parent_check;

  if (node_to_be_decrease == node_to_be_decrease->right_sibling)
    parent_node->child = NULL;

  node_to_be_decrease->left_sibling->right_sibling = node_to_be_decrease->right_sibling;
  node_to_be_decrease->right_sibling->left_sibling = node_to_be_decrease->left_sibling;
  if (node_to_be_decrease == parent_node->child)
    parent_node->child = node_to_be_decrease->right_sibling;
  (parent_node->degree)--;

  node_to_be_decrease->left_sibling = node_to_be_decrease;
  node_to_be_decrease->right_sibling = node_to_be_decrease;
  H->min->left_sibling->right_sibling = node_to_be_decrease;
  node_to_be_decrease->right_sibling = H->min;
  node_to_be_decrease->left_sibling = H->min->left_sibling;
  H->min->left_sibling = node_to_be_decrease;

  node_to_be_decrease->parent = NULL;
  node_to_be_decrease->mark = false;
}

void cascading_cut(FIB_HEAP *H, NODE *parent_node)
{
  NODE *aux;
  aux = parent_node->parent;
  if (aux != NULL)
  {
    if (parent_node->mark == false)
    {
      parent_node->mark = true;
    }
    else
    {
      cut(H, parent_node, aux);
      cascading_cut(H, aux);
    }
  }
}

void decrease_key(FIB_HEAP *H, NODE *node_to_be_decrease, int new_key)
{
  NODE *parent_node;
  if (H == NULL)
  {
    printf("\n FIbonacci heap not created ");
    return;
  }
  if (node_to_be_decrease == NULL)
  {
    printf("Node is not in the heap");
  }

  else
  {
    if (node_to_be_decrease->key < new_key)
    {
      printf("\n Invalid new key for decrease key operation \n ");
    }
    else
    {
      node_to_be_decrease->key = new_key;
      parent_node = node_to_be_decrease->parent;
      if ((parent_node != NULL) && (node_to_be_decrease->key < parent_node->key))
      {
        printf("\n cut called");
        cut(H, node_to_be_decrease, parent_node);
        printf("\n cascading cut called");
        cascading_cut(H, parent_node);
      }
      if (node_to_be_decrease->key < H->min->key)
      {
        H->min = node_to_be_decrease;
      }
    }
  }
}

void *find_node(FIB_HEAP *H, NODE *n, int key, int new_key)
{
  NODE *find_use = n;
  NODE *f = NULL;
  find_use->visited = true;
  if (find_use->key == key)
  {
    find_use->visited = false;
    f = find_use;
    decrease_key(H, f, new_key);
  }
  if (find_use->child != NULL)
  {
    find_node(H, find_use->child, key, new_key);
  }
  if ((find_use->right_sibling->visited != true))
  {
    find_node(H, find_use->right_sibling, key, new_key);
  }

  find_use->visited = false;
}

FIB_HEAP *insertion_procedure()
{
  FIB_HEAP *temp;
  int no_of_nodes, ele, i;
  NODE *new_node;
  temp = (FIB_HEAP *)malloc(sizeof(FIB_HEAP));
  temp = NULL;
  if (temp == NULL)
  {
    temp = make_fib_heap();
  }
  printf(" \n enter number of nodes to be insert = ");
  scanf("%d", &no_of_nodes);
  for (i = 1; i <= no_of_nodes; i++)
  {
    printf("\n node %d and its key value = ", i);
    scanf("%d", &ele);
    insertion(temp, new_node, ele);
  }
  return temp;
}
void Delete_Node(FIB_HEAP *H, int dec_key)
{
  NODE *p = NULL;
  find_node(H, H->min, dec_key, -5000);
  p = extract_min(H);
  if (p != NULL)
    printf("\n Node deleted");
  else
    printf("\n Node not deleted:some error");
}

int main(int argc, char **argv)
{
  NODE *new_node, *min_node, *extracted_min, *node_to_be_decrease, *find_use;
  FIB_HEAP *heap, *h1, *h2;
  int operation_no, new_key, dec_key, ele, i, no_of_nodes;
  heap = (FIB_HEAP *)malloc(sizeof(FIB_HEAP));
  heap = NULL;
  while (1)
  {

    printf(" \n choose below operations \n 1\. Create Fibonacci heap \n 2\. Insert nodes into fibonacci heap \n 3\. Find min \n 4\. Union \n 5\. Extract min \n 6\. Decrease key \n 7.Delete node \n 8\. print heap \n 9\. exit \n enter operation_no = ");
    scanf("%d", &operation_no);

    switch (operation_no)
    {
    case 1:
      heap = make_fib_heap();
      break;

    case 2:
      if (heap == NULL)
      {
        heap = make_fib_heap();
      }
      printf(" enter number of nodes to be insert = ");
      scanf("%d", &no_of_nodes);
      for (i = 1; i <= no_of_nodes; i++)
      {
        printf("\n node %d and its key value = ", i);
        scanf("%d", &ele);
        insertion(heap, new_node, ele);
      }
      break;

    case 3:
      min_node = find_min_node(heap);
      if (min_node == NULL)
        printf("No minimum value");
      else
        printf("\n min value = %d", min_node->key);
      break;

    case 4:
      if (heap == NULL)
      {
        printf("\n no FIbonacci heap is created please create fibonacci heap \n ");
        break;
      }
      h1 = insertion_procedure();
      heap = unionHeap(heap, h1);
      printf("Unified Heap:\n");
      new_print_heap(heap->min);
      break;

    case 5:
      if (heap == NULL)
        printf("Fibonacci heap is empty");
      else
      {
        extracted_min = extract_min(heap);
        printf("\n min value = %d", extracted_min->key);
        printf("\n Updated heap: \n");
        new_print_heap(heap->min);
      }
      break;

    case 6:
      if (heap == NULL)
        printf("Fibonacci heap is empty");
      else
      {
        printf(" \n node to be decreased = ");
        scanf("%d", &dec_key);
        printf(" \n enter the new key = ");
        scanf("%d", &new_key);
        find_use = heap->min;
        find_node(heap, find_use, dec_key, new_key);
        printf("\n Key decreased- Corresponding heap:\n");
        new_print_heap(heap->min);
      }
      break;
    case 7:
      if (heap == NULL)
        printf("Fibonacci heap is empty");
      else
      {
        printf(" \n Enter node key to be deleted = ");
        scanf("%d", &dec_key);
        Delete_Node(heap, dec_key);
        printf("\n Node Deleted- Corresponding heap:\n");
        new_print_heap(heap->min);
        break;
      }
    case 8:
      new_print_heap(heap->min);
      break;

    case 9:
      free(new_node);
      free(heap);
      exit(0);

    default:
      printf("Invalid choice ");
    }
  }
}
// Operations on a Fibonacci heap in C++

#include <iostream>
#include <cmath>
#include <cstdlib>

using namespace std;

struct node
{
  int n;
  int degree;
  node *parent;
  node *child;
  node *left;
  node *right;
  char mark;

  char C;
};

class FibonacciHeap
{
private:
  int nH;

  node *H;

public:
  node *InitializeHeap();
  int Fibonnaci_link(node *, node *, node *);
  node *Create_node(int);
  node *Insert(node *, node *);
  node *Union(node *, node *);
  node *Extract_Min(node *);
  int Consolidate(node *);
  int Display(node *);
  node *Find(node *, int);
  int Decrease_key(node *, int, int);
  int Delete_key(node *, int);
  int Cut(node *, node *, node *);
  int Cascase_cut(node *, node *);
  FibonacciHeap() { H = InitializeHeap(); }
};

node *FibonacciHeap::InitializeHeap()
{
  node *np;
  np = NULL;
  return np;
}

node *FibonacciHeap::Create_node(int value)
{
  node *x = new node;
  x->n = value;
  return x;
}

node *FibonacciHeap::Insert(node *H, node *x)
{
  x->degree = 0;
  x->parent = NULL;
  x->child = NULL;
  x->left = x;
  x->right = x;
  x->mark = 'F';
  x->C = 'N';
  if (H != NULL)
  {
    (H->left)->right = x;
    x->right = H;
    x->left = H->left;
    H->left = x;
    if (x->n < H->n)
      H = x;
  }
  else
  {
    H = x;
  }
  nH = nH + 1;
  return H;
}

int FibonacciHeap::Fibonnaci_link(node *H1, node *y, node *z)
{
  (y->left)->right = y->right;
  (y->right)->left = y->left;
  if (z->right == z)
    H1 = z;
  y->left = y;
  y->right = y;
  y->parent = z;

  if (z->child == NULL)
    z->child = y;

  y->right = z->child;
  y->left = (z->child)->left;
  ((z->child)->left)->right = y;
  (z->child)->left = y;

  if (y->n < (z->child)->n)
    z->child = y;
  z->degree++;
}

node *FibonacciHeap::Union(node *H1, node *H2)
{
  node *np;
  node *H = InitializeHeap();
  H = H1;
  (H->left)->right = H2;
  (H2->left)->right = H;
  np = H->left;
  H->left = H2->left;
  H2->left = np;
  return H;
}

int FibonacciHeap::Display(node *H)
{
  node *p = H;
  if (p == NULL)
  {
    cout << "The Heap is Empty" << endl;
    return 0;
  }
  cout << "The root nodes of Heap are: " << endl;

  do
  {
    cout << p->n;
    p = p->right;
    if (p != H)
    {
      cout << "-->";
    }
  } while (p != H && p->right != NULL);
  cout << endl;
}

node *FibonacciHeap::Extract_Min(node *H1)
{
  node *p;
  node *ptr;
  node *z = H1;
  p = z;
  ptr = z;
  if (z == NULL)
    return z;

  node *x;
  node *np;

  x = NULL;

  if (z->child != NULL)
    x = z->child;

  if (x != NULL)
  {
    ptr = x;
    do
    {
      np = x->right;
      (H1->left)->right = x;
      x->right = H1;
      x->left = H1->left;
      H1->left = x;
      if (x->n < H1->n)
        H1 = x;

      x->parent = NULL;
      x = np;
    } while (np != ptr);
  }

  (z->left)->right = z->right;
  (z->right)->left = z->left;
  H1 = z->right;

  if (z == z->right && z->child == NULL)
    H = NULL;

  else
  {
    H1 = z->right;
    Consolidate(H1);
  }
  nH = nH - 1;
  return p;
}

int FibonacciHeap::Consolidate(node *H1)
{
  int d, i;
  float f = (log(nH)) / (log(2));
  int D = f;
  node *A[D];

  for (i = 0; i <= D; i++)
    A[i] = NULL;

  node *x = H1;
  node *y;
  node *np;
  node *pt = x;

  do
  {
    pt = pt->right;

    d = x->degree;

    while (A[d] != NULL)

    {
      y = A[d];

      if (x->n > y->n)

      {
        np = x;

        x = y;

        y = np;
      }

      if (y == H1)
        H1 = x;
      Fibonnaci_link(H1, y, x);
      if (x->right == x)
        H1 = x;
      A[d] = NULL;
      d = d + 1;
    }

    A[d] = x;
    x = x->right;

  }

  while (x != H1);
  H = NULL;
  for (int j = 0; j <= D; j++)
  {
    if (A[j] != NULL)
    {
      A[j]->left = A[j];
      A[j]->right = A[j];
      if (H != NULL)
      {
        (H->left)->right = A[j];
        A[j]->right = H;
        A[j]->left = H->left;
        H->left = A[j];
        if (A[j]->n < H->n)
          H = A[j];
      }
      else
      {
        H = A[j];
      }
      if (H == NULL)
        H = A[j];
      else if (A[j]->n < H->n)
        H = A[j];
    }
  }
}

int FibonacciHeap::Decrease_key(node *H1, int x, int k)
{
  node *y;
  if (H1 == NULL)
  {
    cout << "The Heap is Empty" << endl;
    return 0;
  }
  node *ptr = Find(H1, x);
  if (ptr == NULL)
  {
    cout << "Node not found in the Heap" << endl;
    return 1;
  }

  if (ptr->n < k)
  {
    cout << "Entered key greater than current key" << endl;
    return 0;
  }
  ptr->n = k;
  y = ptr->parent;
  if (y != NULL && ptr->n < y->n)
  {
    Cut(H1, ptr, y);
    Cascase_cut(H1, y);
  }

  if (ptr->n < H->n)
    H = ptr;

  return 0;
}

int FibonacciHeap::Cut(node *H1, node *x, node *y)

{
  if (x == x->right)
    y->child = NULL;
  (x->left)->right = x->right;
  (x->right)->left = x->left;
  if (x == y->child)
    y->child = x->right;
  y->degree = y->degree - 1;
  x->right = x;
  x->left = x;
  (H1->left)->right = x;
  x->right = H1;
  x->left = H1->left;
  H1->left = x;
  x->parent = NULL;
  x->mark = 'F';
}

int FibonacciHeap::Cascase_cut(node *H1, node *y)
{
  node *z = y->parent;
  if (z != NULL)
  {
    if (y->mark == 'F')
    {
      y->mark = 'T';
    }
    else

    {
      Cut(H1, y, z);
      Cascase_cut(H1, z);
    }
  }
}

node *FibonacciHeap::Find(node *H, int k)
{
  node *x = H;
  x->C = 'Y';
  node *p = NULL;
  if (x->n == k)
  {
    p = x;
    x->C = 'N';
    return p;
  }

  if (p == NULL)
  {
    if (x->child != NULL)
      p = Find(x->child, k);
    if ((x->right)->C != 'Y')
      p = Find(x->right, k);
  }

  x->C = 'N';
  return p;
}

int FibonacciHeap::Delete_key(node *H1, int k)
{
  node *np = NULL;
  int t;
  t = Decrease_key(H1, k, -5000);
  if (!t)
    np = Extract_Min(H);
  if (np != NULL)
    cout << "Key Deleted" << endl;
  else
    cout << "Key not Deleted" << endl;
  return 0;
}

int main()
{
  int n, m, l;
  FibonacciHeap fh;
  node *p;
  node *H;
  H = fh.InitializeHeap();

  p = fh.Create_node(7);
  H = fh.Insert(H, p);
  p = fh.Create_node(17);
  H = fh.Insert(H, p);
  p = fh.Create_node(26);
  H = fh.Insert(H, p);
  p = fh.Create_node(1);
  H = fh.Insert(H, p);

  fh.Display(H);

  p = fh.Extract_Min(H);
  if (p != NULL)
    cout << "The node with minimum key: " << p->n << endl;
  else
    cout << "Heap is empty" << endl;

  m = 26;
  l = 16;
  fh.Decrease_key(H, m, l);

  m = 16;
  fh.Delete_key(H, m);
}

复杂度

减小键 O(1)
删除节点 O(log n)