默克尔树简介
默克尔树也称为哈希树,是一种用于数据验证和同步的数据结构。
它是一个树数据结构,其中每个非叶节点都是其子节点的哈希。所有的叶子节点都在相同的深度,并且尽可能地向左。
它维护数据完整性并为此使用散列函数。
哈希函数:
因此,在了解 Merkle 树的工作原理之前,我们需要了解哈希函数的工作原理。
散列函数将输入映射到固定输出,该输出称为散列。
每个输入的输出都是唯一的,这可以对数据进行指纹识别。
因此,可以通过它们的哈希轻松识别大量数据。
这是一棵二叉默克尔树,顶部哈希是整棵树的哈希。
- 树的这种结构允许有效映射大量数据,并且可以轻松识别对数据所做的微小更改。
- 如果我们想知道数据变化发生在哪里,那么我们可以检查数据是否与根哈希一致,我们不必遍历整个结构,而只需遍历结构的一小部分。
- 根哈希用作整个数据的指纹。
对于二叉默克尔树
Operation | Complexity |
---|---|
Space | O(n) |
Searching | O(logn) |
Traversal | O(n) |
Insertion | O(logn) |
Deletion | O(logn) |
Synchronization | O(logn) |
应用:
- Merkle 树在分布式系统中很有用,在这些系统中,相同的数据应该存在于多个地方。
- 默克尔树可用于检查不一致。
- Apache Cassandra 使用 Merkle 树来检测整个数据库副本之间的不一致。
- 它用于比特币和区块链。
此代码由 Amit Das 提供。
C++
// CPP code for the above data structure
#include
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)