Montón de Fibonacci: tecla de eliminación, extracción mínima y disminución

En la última publicación, discutimos la inserción y unión de montones de Fibonacci. En esta publicación, discutiremos las operaciones Extract_min(), Decrease_key() y Deletion() en el montón de Fibonacci.

Prerrequisitos:  
Montón de Fibonacci (Introducción)  
Montón de Fibonacci – Inserción y Unión

Extract_min(): creamos una función para eliminar el Node mínimo y establecer el puntero mínimo en el valor mínimo en el montón restante. Se sigue el siguiente algoritmo:  

  1. Eliminar el Node min.
  2. Establezca la cabeza en el siguiente Node mínimo y agregue todos los árboles del Node eliminado en la lista raíz.
  3. Cree una array de punteros de grado del tamaño del Node eliminado.
  4. Establezca el puntero de grado en el Node actual.
  5. Mover al siguiente Node.
    • Si los grados son diferentes, establezca el puntero de grado en el siguiente Node.
    • Si los grados son iguales, únase a los árboles de Fibonacci mediante la operación de unión.
  6. Repita los pasos 4 y 5 hasta completar el montón.

Ejemplo: 
 

Fibonacci Heap – Deletion, Extract min and Decrease key 1

Decrease_key(): Para disminuir el valor de cualquier elemento en el montón, seguimos el siguiente algoritmo:

  • Disminuya el valor del Node ‘x’ al nuevo valor elegido.
  • CASO 1) Si no se viola la propiedad min-heap, 
    • Actualice el puntero mínimo si es necesario.
  • CASO 2) Si se viola la propiedad min-heap y el padre de ‘x’ no está marcado, 
    • Corta el vínculo entre ‘x’ y su padre.
    • Marque el padre de ‘x’.
    • Agregue el árbol enraizado en ‘x’ a la lista de raíces y actualice el puntero mínimo si es necesario.
  • CASO 3) Si se viola la propiedad min-heap y se marca el padre de ‘x’, 
    • Corta el vínculo entre ‘x’ y su padre p[x].
    • Agregue ‘x’ a la lista raíz, actualizando el puntero mínimo si es necesario.
    • Cortar el vínculo entre p[x] y p[p[x]].
    • Agregue p[x] a la lista raíz, actualizando el puntero mínimo si es necesario.
    • Si p[p[x]] no está marcado, márquelo.
    • De lo contrario, corte p[p[x]] y repita los pasos 4.2 a 4.5, tomando p[p[x]] como ‘x’.

Ejemplo: 

Fibonacci Heap – Deletion, Extract min and Decrease key 2

Eliminación(): para eliminar cualquier elemento en un montón de Fibonacci, se sigue el siguiente algoritmo:

  1. Disminuya el valor del Node a eliminar ‘x’ al mínimo mediante la función Decrease_key().
  2. Al usar la propiedad min-heap, apile el montón que contiene ‘x’, trayendo ‘x’ a la lista raíz.
  3. Aplique el algoritmo Extract_min() al montón de Fibonacci.

Ejemplo:  

Fibonacci Heap – Deletion, Extract min and Decrease key 3

El siguiente es un programa para demostrar las operaciones Extraer min(), Eliminar() y Disminuir tecla() en un Montón de Fibonacci: 

C++

// C++ program to demonstrate Extract min, Deletion()
// and Decrease key() operations in a fibonacci heap
#include <cmath>
#include <cstdlib>
#include <iostream>
#include <malloc.h>
using namespace std;
  
// Creating a structure to represent a node in the heap
struct node {
    node* parent; // Parent pointer
    node* child; // Child pointer
    node* left; // Pointer to the node on the left
    node* right; // Pointer to the node on the right
    int key; // Value of the node
    int degree; // Degree of the node
    char mark; // Black or white mark of the node
    char c; // Flag for assisting in the Find node function
};
  
// Creating min pointer as "mini"
struct node* mini = NULL;
  
// Declare an integer for number of nodes in the heap
int no_of_nodes = 0;
  
// Function to insert a node in heap
void insertion(int val)
{
    struct node* new_node = new node();
    new_node->key = val;
    new_node->degree = 0;
    new_node->mark = 'W';
    new_node->c = 'N';
    new_node->parent = NULL;
    new_node->child = NULL;
    new_node->left = new_node;
    new_node->right = new_node;
    if (mini != NULL) {
        (mini->left)->right = new_node;
        new_node->right = mini;
        new_node->left = mini->left;
        mini->left = new_node;
        if (new_node->key < mini->key)
            mini = new_node;
    }
    else {
        mini = new_node;
    }
    no_of_nodes++;
}
// Linking the heap nodes in parent child relationship
void Fibonnaci_link(struct node* ptr2, struct node* ptr1)
{
    (ptr2->left)->right = ptr2->right;
    (ptr2->right)->left = ptr2->left;
    if (ptr1->right == ptr1)
        mini = ptr1;
    ptr2->left = ptr2;
    ptr2->right = ptr2;
    ptr2->parent = ptr1;
    if (ptr1->child == NULL)
        ptr1->child = ptr2;
    ptr2->right = ptr1->child;
    ptr2->left = (ptr1->child)->left;
    ((ptr1->child)->left)->right = ptr2;
    (ptr1->child)->left = ptr2;
    if (ptr2->key < (ptr1->child)->key)
        ptr1->child = ptr2;
    ptr1->degree++;
}
// Consolidating the heap
void Consolidate()
{
    int temp1;
    float temp2 = (log(no_of_nodes)) / (log(2));
    int temp3 = temp2;
    struct node* arr[temp3+1];
    for (int i = 0; i <= temp3; i++)
        arr[i] = NULL;
    node* ptr1 = mini;
    node* ptr2;
    node* ptr3;
    node* ptr4 = ptr1;
    do {
        ptr4 = ptr4->right;
        temp1 = ptr1->degree;
        while (arr[temp1] != NULL) {
            ptr2 = arr[temp1];
            if (ptr1->key > ptr2->key) {
                ptr3 = ptr1;
                ptr1 = ptr2;
                ptr2 = ptr3;
            }
            if (ptr2 == mini)
                mini = ptr1;
            Fibonnaci_link(ptr2, ptr1);
            if (ptr1->right == ptr1)
                mini = ptr1;
            arr[temp1] = NULL;
            temp1++;
        }
        arr[temp1] = ptr1;
        ptr1 = ptr1->right;
    } while (ptr1 != mini);
    mini = NULL;
    for (int j = 0; j <= temp3; j++) {
        if (arr[j] != NULL) {
            arr[j]->left = arr[j];
            arr[j]->right = arr[j];
            if (mini != NULL) {
                (mini->left)->right = arr[j];
                arr[j]->right = mini;
                arr[j]->left = mini->left;
                mini->left = arr[j];
                if (arr[j]->key < mini->key)
                    mini = arr[j];
            }
            else {
                mini = arr[j];
            }
            if (mini == NULL)
                mini = arr[j];
            else if (arr[j]->key < mini->key)
                mini = arr[j];
        }
    }
}
  
// Function to extract minimum node in the heap
void Extract_min()
{
    if (mini == NULL)
        cout << "The heap is empty" << endl;
    else {
        node* temp = mini;
        node* pntr;
        pntr = temp;
        node* x = NULL;
        if (temp->child != NULL) {
  
            x = temp->child;
            do {
                pntr = x->right;
                (mini->left)->right = x;
                x->right = mini;
                x->left = mini->left;
                mini->left = x;
                if (x->key < mini->key)
                    mini = x;
                x->parent = NULL;
                x = pntr;
            } while (pntr != temp->child);
        }
        (temp->left)->right = temp->right;
        (temp->right)->left = temp->left;
        mini = temp->right;
        if (temp == temp->right && temp->child == NULL)
            mini = NULL;
        else {
            mini = temp->right;
            Consolidate();
        }
        no_of_nodes--;
    }
}
  
// Cutting a node in the heap to be placed in the root list
void Cut(struct node* found, struct node* temp)
{
    if (found == found->right)
        temp->child = NULL;
  
    (found->left)->right = found->right;
    (found->right)->left = found->left;
    if (found == temp->child)
        temp->child = found->right;
  
    temp->degree = temp->degree - 1;
    found->right = found;
    found->left = found;
    (mini->left)->right = found;
    found->right = mini;
    found->left = mini->left;
    mini->left = found;
    found->parent = NULL;
    found->mark = 'B';
}
  
// Recursive cascade cutting function
void Cascase_cut(struct node* temp)
{
    node* ptr5 = temp->parent;
    if (ptr5 != NULL) {
        if (temp->mark == 'W') {
            temp->mark = 'B';
        }
        else {
            Cut(temp, ptr5);
            Cascase_cut(ptr5);
        }
    }
}
  
// Function to decrease the value of a node in the heap
void Decrease_key(struct node* found, int val)
{
    if (mini == NULL)
        cout << "The Heap is Empty" << endl;
  
    if (found == NULL)
        cout << "Node not found in the Heap" << endl;
  
    found->key = val;
  
    struct node* temp = found->parent;
    if (temp != NULL && found->key < temp->key) {
        Cut(found, temp);
        Cascase_cut(temp);
    }
    if (found->key < mini->key)
        mini = found;
}
  
// Function to find the given node
void Find(struct node* mini, int old_val, int val)
{
    struct node* found = NULL;
    node* temp5 = mini;
    temp5->c = 'Y';
    node* found_ptr = NULL;
    if (temp5->key == old_val) {
        found_ptr = temp5;
        temp5->c = 'N';
        found = found_ptr;
        Decrease_key(found, val);
    }
    if (found_ptr == NULL) {
        if (temp5->child != NULL)
            Find(temp5->child, old_val, val);
        if ((temp5->right)->c != 'Y')
            Find(temp5->right, old_val, val);
    }
    temp5->c = 'N';
    found = found_ptr;
}
  
// Deleting a node from the heap
void Deletion(int val)
{
    if (mini == NULL)
        cout << "The heap is empty" << endl;
    else {
  
        // Decreasing the value of the node to 0
        Find(mini, val, 0);
  
        // Calling Extract_min function to
        // delete minimum value node, which is 0
        Extract_min();
        cout << "Key Deleted" << endl;
    }
}
  
// Function to display the heap
void display()
{
    node* ptr = mini;
    if (ptr == NULL)
        cout << "The Heap is Empty" << endl;
  
    else {
        cout << "The root nodes of Heap are: " << endl;
        do {
            cout << ptr->key;
            ptr = ptr->right;
            if (ptr != mini) {
                cout << "-->";
            }
        } while (ptr != mini && ptr->right != NULL);
        cout << endl
             << "The heap has " << no_of_nodes << " nodes" << endl
             << endl;
    }
}
  
// Driver code
int main()
{
    // We will create a heap and insert 3 nodes into it
    cout << "Creating an initial heap" << endl;
    insertion(5);
    insertion(2);
    insertion(8);
  
    // Now we will display the root list of the heap
    display();
  
    // Now we will extract the minimum value node from the heap
    cout << "Extracting min" << endl;
    Extract_min();
    display();
  
    // Now we will decrease the value of node '8' to '7'
    cout << "Decrease value of 8 to 7" << endl;
    Find(mini, 8, 7);
    display();
  
    // Now we will delete the node '7'
    cout << "Delete the node 7" << endl;
    Deletion(7);
    display();
  
    return 0;
}

Python3

# Python3 program to demonstrate Extract min, Deletion()
# and Decrease key() operations in a fibonacci heap
import math
  
# Creating a class to represent a node in the heap
class node:
    def __init__(self):
        parent=None # Parent pointer
        child=None # Child pointer
        left=None # Pointer to the node on the left
        right=None # Pointer to the node on the right
        key=-1 # Value of the node
        degree=-1 # Degree of the node
        mark='' # Black or white mark of the node
        c='' # Flag for assisting in the Find node function
  
# Creating min pointer as "mini"
mini = None
  
# Declare an integer for number of nodes in the heap
no_of_nodes = 0
  
# Function to insert a node in heap
def insertion(val):
    global mini,no_of_nodes
  
    new_node = node()
    new_node.key = val
    new_node.degree = 0
    new_node.mark = 'W'
    new_node.c = 'N'
    new_node.parent = None
    new_node.child = None
    new_node.left = new_node
    new_node.right = new_node
    if (mini != None):
        mini.left.right = new_node
        new_node.right = mini
        new_node.left = mini.left
        mini.left = new_node
        if (new_node.key < mini.key):
            mini = new_node
    else:
        mini = new_node
    no_of_nodes+=1
  
#  Linking the heap nodes in parent child relationship
def Fibonnaci_link(ptr2, ptr1):
    ptr2.left.right = ptr2.right
    ptr2.right.left = ptr2.left
    if (ptr1.right == ptr1):
        mini = ptr1
    ptr2.left = ptr2
    ptr2.right = ptr2
    ptr2.parent = ptr1
    if (ptr1.child == None):
        ptr1.child = ptr2
    ptr2.right = ptr1.child
    ptr2.left = ptr1.child.left
    ptr1.child.left.right = ptr2
    ptr1.child.left = ptr2
    if ptr2.key < ptr1.child.key:
        ptr1.child = ptr2
    ptr1.degree+=1
  
# Consolidating the heap
def Consolidate():
      
    global mini
    temp2 = math.log2(no_of_nodes)
    temp3 = int(temp2)
    arr=[None]*(temp3+1)
    for i in range(temp3+1):
        arr[i] = None
    ptr1 = mini
    ptr4 = ptr1
    while True:
        ptr4 = ptr4.right
        temp1 = ptr1.degree
        while (arr[temp1] != None):
            ptr2 = arr[temp1]
            if (ptr1.key > ptr2.key):
                ptr3 = ptr1
                ptr1 = ptr2
                ptr2 = ptr3
            if (ptr2 == mini):
                mini = ptr1
            Fibonnaci_link(ptr2, ptr1)
            if (ptr1.right == ptr1):
                mini = ptr1
            arr[temp1] = None
            temp1+=1
        arr[temp1] = ptr1
        ptr1 = ptr1.right
        if (ptr1 == mini):
            break
    mini = None
    for j in range(temp3+1):
        if (arr[j] != None):
            arr[j].left = arr[j]
            arr[j].right = arr[j]
            if (mini != None) :
                mini.left.right = arr[j]
                arr[j].right = mini
                arr[j].left = mini.left
                mini.left = arr[j]
                if (arr[j].key < mini.key):
                    mini = arr[j]
            else:
                mini = arr[j]
            if mini == None:
                mini = arr[j]
            elif arr[j].key < mini.key:
                mini = arr[j]
      
  
# Function to extract minimum node in the heap
def Extract_min():
  
    global mini,no_of_nodes
    if mini == None:
        print("The heap is empty")
    else:
        temp = mini
        pntr = temp
        x = None
        if (temp.child != None):
  
            x = temp.child
            while(True):
                pntr = x.right
                mini.left.right = x
                x.right = mini
                x.left = mini.left
                mini.left = x
                if x.key < mini.key:
                    mini = x
                x.parent = None
                x = pntr
                if (pntr == temp.child):
                    break
  
        temp.left.right = temp.right
        temp.right.left = temp.left
        mini = temp.right
        if temp == temp.right and temp.child == None:
            mini = None
        else:
            mini = temp.right
            Consolidate()
        no_of_nodes-=1
  
  
  
# Cutting a node in the heap to be placed in the root list
def Cut(found, temp):
  
    if (found == found.right):
        temp.child = None
  
    found.left.right = found.right
    found.right.left = found.left
    if (found == temp.child):
        temp.child = found.right
  
    temp.degree = temp.degree - 1
    found.right = found
    found.left = found
    mini.left.right = found
    found.right = mini
    found.left = mini.left
    mini.left = found
    found.parent = None
    found.mark = 'B'
  
# Recursive cascade cutting function
def Cascase_cut(temp):
  
    ptr5 = temp.parent
    if (ptr5 != None):
        if (temp.mark == 'W'):
            temp.mark = 'B'
        else:
            Cut(temp, ptr5)
            Cascase_cut(ptr5)
  
# Function to decrease the value of a node in the heap
def Decrease_key(found, val):
  
    global mini
    if (mini == None):
        print("The Heap is Empty")
  
    if found == None:
        print("Node not found in the Heap")
  
    found.key = val
  
    temp = found.parent
    if (temp != None and found.key < temp.key):
        Cut(found, temp)
        Cascase_cut(temp)
  
    if (found.key < mini.key):
        mini = found
  
  
# Function to find the given node
def Find(mini, old_val, val):
  
    found = None
    temp5 = mini
    temp5.c = 'Y'
    found_ptr = None
    if (temp5.key == old_val):
        found_ptr = temp5
        temp5.c = 'N'
        found = found_ptr
        Decrease_key(found, val)
  
    if (found_ptr == None):
        if (temp5.child != None):
            Find(temp5.child, old_val, val)
        if temp5.right.c != 'Y':
            Find(temp5.right, old_val, val)
    temp5.c = 'N'
    found = found_ptr
  
  
# Deleting a node from the heap
def Deletion(val):
  
    if (mini == None):
        print("The heap is empty")
    else:
        # Decreasing the value of the node to 0
        Find(mini, val, 0)
  
        # Calling Extract_min function to
        # delete minimum value node, which is 0
        Extract_min()
        print("Key Deleted")
  
  
# Function to display the heap
def display():
    ptr = mini
    if (ptr == None):
        print("The Heap is Empty")
  
    else:
        print("The root nodes of Heap are: ")
        while(True):
            print(ptr.key,end='')
            ptr = ptr.right
            if (ptr != mini):
                print("-->",end='')
            if not(ptr != mini and ptr.right != None):
                break
        print()
        print("The heap has {} nodes".format(no_of_nodes))
  
# Driver code
if __name__ == '__main__':
  
    # We will create a heap and insert 3 nodes into it
    print("Creating an initial heap")
    insertion(5)
    insertion(2)
    insertion(8)
  
    # Now we will display the root list of the heap
    display()
  
    # Now we will extract the minimum value node from the heap
    print("Extracting min")
    Extract_min()
    display()
  
    # Now we will decrease the value of node '8' to '7'
    print("Decrease value of 8 to 7")
    Find(mini, 8, 7)
    display()
  
    print("Now we will delete the node '7'")
    print("Delete the node 7")
    Deletion(7)
    display()
  
# This code is contributed by Amartya Ghosh
Producción: 

Creating an initial heap
The root nodes of Heap are: 
2-->5-->8
The heap has 3 nodes

Extracting min
The root nodes of Heap are: 
5
The heap has 2 nodes

Decrease value of 8 to 7
The root nodes of Heap are: 
5
The heap has 2 nodes

Delete the node 7
Key Deleted
The root nodes of Heap are: 
5
The heap has 1 nodes

 

Publicación traducida automáticamente

Artículo escrito por mohak_mahajan y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *