Introduction to Merkle Tree

02 Feb, 2022
Merkle tree also known as hash tree is a data structure used for data verification and synchronization. It is a tree data structure where each non-leaf node is a hash of it’s child nodes. All the leaf nodes are at the same depth and are as far left as possible. It maintains data integrity and uses hash functions for this purpose. Hash Functions: So before understanding how Merkle trees work, we need to understand how hash functions work. A hash function maps an input to a fixed output and this output is called hash. The output is unique for every input and this enables fingerprinting of data. So, huge amounts of data can be easily identified through their hash.  
This is a binary merkel tree, the top hash is a hash of the entire tree.  
This structure of the tree allows efficient mapping of huge data and small changes made to the data can be easily identified.
If we want to know where data change has occurred then we can check if data is consistent with root hash and we will not have to traverse the whole structure but only a small part of the structure.
The root hash is used as the fingerprint for the entire data.
For a Binary Merkel tree  
Applications:  
Merkle trees are useful in distributed systems where same data should exist in multiple places.
Merkle trees can be used to check inconsistencies.
Apache Cassandra uses Merkle trees to detect inconsistencies between replicas of entire databases.
It is used in bitcoin and blockchain.
This code is contributed by 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 ofparticular 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 Codeint 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)
 
Amit_Das
sumitgumber28
Binary Tree
Hash
Picked
Technical Scripter 2018
Technical Scripter
Tree
Hash
Tree
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
Tree Traversals (Inorder, Preorder and Postorder)
Binary Tree | Set 1 (Introduction)
Level Order Binary Tree Traversal
AVL Tree | Set 1 (Insertion)
Introduction to Data Structures
Introduction to Tree Data Structure
Inorder Tree Traversal without Recursion
What is Data Structure: Types, Classifications and Applications
Write a Program to Find the Maximum Depth or Height of a Tree
Binary Tree | Set 3 (Types of Binary Tree)