Introducción al árbol de Merkle

El árbol Merkle, también conocido como árbol hash, es una estructura de datos utilizada para la verificación y sincronización de datos. 
Es una estructura de datos de árbol donde cada Node que no es hoja es un hash de sus Nodes secundarios. Todos los Nodes hoja están a la misma profundidad y lo más a la izquierda posible. 
Mantiene la integridad de los datos y utiliza funciones hash para este propósito. 
Funciones hash: 
Entonces, antes de entender cómo funcionan los árboles de Merkle, debemos entender cómo funcionan las funciones hash. 
Una función hash asigna una entrada a una salida fija y esta salida se llama hash. 
La salida es única para cada entrada y esto permite la toma de huellas dactilares de los datos. 
Por lo tanto, se pueden identificar fácilmente grandes cantidades de datos a través de su hash. 
 

Este es un árbol Merkel binario , el hash superior es un hash de todo el árbol. 
 

  • Esta estructura del árbol permite un mapeo eficiente de grandes datos y los pequeños cambios realizados en los datos pueden identificarse fácilmente.
  • Si queremos saber dónde se ha producido el cambio de datos, podemos comprobar si los datos son coherentes con el hash raíz y no tendremos que atravesar toda la estructura, sino solo una pequeña parte de la estructura.
  • El hash raíz se utiliza como huella digital para todos los datos.

Para un árbol binario de Merkel 
 

Operación Complejidad
Espacio En)
buscando O (inicio de sesión)
El recorrido En)
Inserción O (inicio de sesión)
Supresión O (inicio de sesión)
Sincronización O (inicio de sesión)

Aplicaciones: 
 

  • Los árboles de Merkle son útiles en sistemas distribuidos donde los mismos datos deben existir en varios lugares.
  • Los árboles de Merkle se pueden utilizar para comprobar las inconsistencias.
  • Apache Cassandra usa árboles Merkle para detectar inconsistencias entre réplicas de bases de datos completas.
  • Se utiliza en bitcoin y blockchain.

Este código es aportado por Amit Das .

C++

// CPP code for the above data structure
#include<bits/stdc++.h>
using namespace std;
 
/* determines the maximum capacity of
   Hash Tree */
int maxim = 10;        
 
/* determines the number of elements
   present in Hash Tree */
int size = 0;         
 
/* node for storing an item in a Binary Tree */
struct node
{
  int key;
  int value;
  struct node *left;
  struct node *right;
};
 
/* for storing a Binary Tree at each index
   of Hash Tree */
struct bst
{
   
  /* head pointing to the root of Binary Tree */
  struct node *head;
};
 
 
 
struct bst *arr;
 
 
 
void insert_element(struct node *tree,
                          struct node *item);
 
struct node* find(struct node *tree, int key);
 
struct node* remove_element(struct node *tree,
                                     int key);
 
void display_tree(struct node *tree);
 
/* this function creates an index corresponding
   to the every given key */
int hashcode(int key)
{
  return (key % maxim);
}
 
void add(int key, int value)
{
  int index = hashcode(key);
 
  /* extracting Binary Tree at the given index */
  struct node *tree = (struct node*) arr[index].head;
   
  /* creating an item to insert in the hashTree */
  struct node *new_item = (struct node*)
                         malloc(sizeof(struct node));
 
  new_item->key = key;
  new_item->value = value;
  new_item->left = NULL;
  new_item->right = NULL;
 
  if (tree == NULL)
  {
 
    /* absence of Binary Tree at a given
       index of Hash Tree */
    cout << "Inserting " << key << " and " <<
                                 value << endl;
    arr[index].head = new_item;
    size++;
  }
 
  else
  {
 
    /* a Binary Tree is present at given index
       of Hash Tree */
    struct node *temp = find(tree, key);
 
    if (temp == NULL)
    {
 
      /*
       * Key not found in existing Binary Tree
       * Adding the key in existing Binary Tree
       */
 
      cout << "Inserting " << key << "and" <<
                                value << endl;
 
      insert_element(tree, new_item);
      size++;
    }
 
    else
    {
 
      /*
        * Key already present in existing Binary Tree
        * Updating the value of already existing key
       */
      
      temp->value = value;
    }
  }
}
 
/*
 * this function finds the given key in the Binary Tree
 * returns the node containing the key
 * returns NULL in case key is not present
 */
struct node* find(struct node *tree, int key)
{
  if (tree == NULL)
  {
    return NULL;
  }
  if (tree->key == key)
  {
    return tree;
  }
  else if (key < tree->key)
  {
    return find(tree->left, key);
  }
  else
  {
    return find(tree->right, key);
  }
}
 
/* this function inserts the newly created node
   in the existing Binary Tree */
void insert_element(struct node *tree,
                              struct node *item)
{
 
  if (item->key < tree->key)
  {
    if (tree->left == NULL)
    {
      tree->left = item;
      return;
    }
    else
    {
      insert_element(tree->left, item);
      return;
    }
  }
 
  else if (item->key > tree->key)
  {
    if (tree->right == NULL)
    {
      tree->right = item;
      return;
    }
    else
    {
      insert_element(tree->right, item);
      return;
    }
  }
}
 
/* displays the content of hash Tree */
void display()
{
  int i = 0;
  for(i = 0; i < maxim; i++)
  {
    struct node *tree = arr[i].head;
    if (tree == NULL)
    {
      cout << "arr[" << i << "] has no
                             elements" << endl;
    }
    else
    {
      cout << "arr[" << i << "] has
                             elements" << endl;
      display_tree(tree);
    }
  }
}
 
/* displays content of binary tree of
particular index */
void display_tree(struct node *tree)
{
 
  if (tree == NULL)
  {
    return;
  }
 
  cout << tree->key << " and " <<
                          tree->value << "   ";
 
  if (tree->left != NULL)
  {
    display_tree(tree->left);
  }
   
  if (tree->right != NULL)
  {
    display_tree(tree->right);
  }
}
 
/* for initializing the hash Tree */
void init()
{
  int i = 0;
  for(i = 0; i < maxim; i++)
  {
    arr[i].head = NULL;
  }
}
 
/* returns the size of hash Tree */
int size_of_hashTree()
{
  return size;
}
 
/* to del a key from hash Tree */
void del(int key)
{
  int index = hashcode(key);
  struct node *tree = (struct node*)arr[index].head;
  if (tree == NULL)
  {
    cout << key << " Key not present" << endl;
  }
 
  else
  {
    struct node *temp = find(tree, key);
    if (temp == NULL)
    {
      cout << key << " is not present";
    }
    else
    {
      tree = remove_element(tree, key);
      cout << key << " has been removed
                      form the hash tree" << endl;
    }
  }
}
 
struct node* remove_element(struct node *tree,
                                      int key)
{
 
  if (tree == NULL)
  {
    return NULL;
  }
 
  if (key < tree->key)
  {
    tree->left = remove_element(tree->left, key);
    return tree;
  }
 
  else if (key > tree->key)
  {
    tree->right = remove_element(tree->right, key);
    return tree;
  }
 
  else
  {
     
    /* reached the node */
    if (tree->left == NULL  &&  tree->right == NULL)
    {
      size--;
      return tree->left;
    }
 
    else if (tree->left != NULL  &&  tree->right == NULL)
    {
      size--;
      return tree->left;
    }
     
    else if (tree->left == NULL  &&  tree->right != NULL)
    {
      size--;
      return tree->right;
    }
 
    else
    {
      struct node *left_one = tree->left;
      while (left_one->right != NULL)
      {
        left_one = left_one->right;
      }
 
      tree->key = left_one->key;
      tree->value = left_one->value;
      tree->left = remove_element(tree->left,
                                     tree->key);
      return tree;
    }
  }
}
 
// Driver Code
int main()
{
  int choice, key, value, n, c;
  arr = (struct bst*)malloc(maxim *
                             sizeof(struct bst*));
  init();
  do
  {
    cout << "Implementation of Hash Tree" << endl;
    cout << "MENU-: \n1.Insert an item in the Hash Tree"
      "\n2.Remove an item from the Hash Tree"
      "\n3.Check the size of Hash Tree"
      "\n4.Display Hash Tree"
      "\n\n Please enter your choice-:";
     
    cin >> choice;
    switch(choice)
    {
       
      case 1:
        cout << "Inserting element in
                           Hash Tree" << endl;
        cout << "Enter key and value-:    ";
        cin >> key >> value;
        add(key, value);
        break;
         
      case 2:
        cout << "Deleting item from Hash Tree
                   \n Enter the key to delete-:";
        cin >> key;
        del(key);
        break;
         
      case 3:
        n = size_of_hashTree();
        cout << "Size of Hash Tree is-:" << n << endl;
        break;
         
      case 4:
        display();
        break;
         
      default:
        cout << "Wrong Input" << endl;
    }
    cout << "\n Do you want to continue-:
                             (press 1 for yes)     ";
    cin >> c;
 
  }while(c == 1);
  return 0;
}
 
//This code is contributed by Amit Das(amit_das)

Publicación traducida automáticamente

Artículo escrito por lakshita 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 *