Treap |集2(执行搜索、插入和删除)

我们强烈建议将第1组作为这篇文章的先决条件。 Treap(随机二叉搜索树) 本文讨论了搜索、插入和删除的实现。 搜索: 等同于 标准BST搜索 。搜索时不考虑优先级。

null

CPP

// C function to search a given key in a given BST
TreapNode* search(TreapNode* root, int key)
{
// Base Cases: root is null or key is present at root
if (root == NULL || root->key == key)
return root;
// Key is greater than root's key
if (root->key < key)
return search(root->right, key);
// Key is smaller than root's key
return search(root->left, key);
}


插入 1) 创建键等于x且值等于随机值的新节点。 2) 执行标准 BST插件 . 3) 新插入的节点具有随机优先级,因此可能会违反Max Heap属性。。使用旋转来确保插入节点的优先级遵循max heap属性。 在插入过程中,我们递归地遍历插入节点的所有祖先。 a) 如果在左子树中插入了新节点,并且左子树的根具有更高的优先级,则执行右旋转。 b) 如果在右子树中插入了新节点,并且右子树的根具有更高的优先级,则执行左旋转。

CPP

/* Recursive implementation of insertion in Treap */
TreapNode* insert(TreapNode* root, int key)
{
// If root is NULL, create a new node and return it
if (!root)
return newNode(key);
// If key is smaller than root
if (key <= root->key)
{
// Insert in left subtree
root->left = insert(root->left, key);
// Fix Heap property if it is violated
if (root->left->priority > root->priority)
root = rightRotate(root);
}
else // If key is greater
{
// Insert in right subtree
root->right = insert(root->right, key);
// Fix Heap property if it is violated
if (root->right->priority > root->priority)
root = leftRotate(root);
}
return root;
}


删除: 这里的delete实现与中讨论的步骤略有不同 以前的职位 . 1) 如果节点是叶,请将其删除。 2) 如果节点有一个子节点为NULL,另一个子节点为非NULL,则用非空子节点替换节点。 3) 如果节点的两个子节点都为非NULL,则查找左、右子节点的最大值。 ….a) 如果右子节点的优先级更高,则在节点处执行左旋转 ….b) 如果左子节点的优先级更高,则在节点处执行右旋转。 第3步的想法是将节点向下移动,这样我们就可以得到案例1或案例2。

CPP

/* Recursive implementation of Delete() */
TreapNode* deleteNode(TreapNode* root, int key)
{
// Base case
if (root == NULL) return root;
// IF KEYS IS NOT AT ROOT
if (key < root->key)
root->left = deleteNode(root->left, key);
else if (key > root->key)
root->right = deleteNode(root->right, key);
// IF KEY IS AT ROOT
// If left is NULL
else if (root->left == NULL)
{
TreapNode *temp = root->right;
delete (root);
root = temp; // Make right child as root
}
// If Right is NULL
else if (root->right == NULL)
{
TreapNode *temp = root->left;
delete (root);
root = temp; // Make left child as root
}
// If key is at root and both left and right are not NULL
else if (root->left->priority < root->right->priority)
{
root = leftRotate(root);
root->left = deleteNode(root->left, key);
}
else
{
root = rightRotate(root);
root->right = deleteNode(root->right, key);
}
return root;
}


演示所有操作的完整程序

CPP

// C++ program to demonstrate search, insert and delete in Treap
#include <bits/stdc++.h>
using namespace std;
// A Treap Node
struct TreapNode
{
int key, priority;
TreapNode *left, *right;
};
/* T1, T2 and T3 are subtrees of the tree rooted with y
(on left side) or x (on right side)
y                               x
/      Right Rotation          /
x   T3   – – – – – – – >        T1   y
/        < - - - - - - -            /
T1  T2     Left Rotation            T2  T3 */
// A utility function to right rotate subtree rooted with y
// See the diagram given above.
TreapNode *rightRotate(TreapNode *y)
{
TreapNode *x = y->left,  *T2 = x->right;
// Perform rotation
x->right = y;
y->left = T2;
// Return new root
return x;
}
// A utility function to left rotate subtree rooted with x
// See the diagram given above.
TreapNode *leftRotate(TreapNode *x)
{
TreapNode *y = x->right, *T2 = y->left;
// Perform rotation
y->left = x;
x->right = T2;
// Return new root
return y;
}
/* Utility function to add a new key */
TreapNode* newNode( int key)
{
TreapNode* temp = new TreapNode;
temp->key = key;
temp->priority = rand ()%100;
temp->left = temp->right = NULL;
return temp;
}
// C function to search a given key in a given BST
TreapNode* search(TreapNode* root, int key)
{
// Base Cases: root is null or key is present at root
if (root == NULL || root->key == key)
return root;
// Key is greater than root's key
if (root->key < key)
return search(root->right, key);
// Key is smaller than root's key
return search(root->left, key);
}
/* Recursive implementation of insertion in Treap */
TreapNode* insert(TreapNode* root, int key)
{
// If root is NULL, create a new node and return it
if (!root)
return newNode(key);
// If key is smaller than root
if (key <= root->key)
{
// Insert in left subtree
root->left = insert(root->left, key);
// Fix Heap property if it is violated
if (root->left->priority > root->priority)
root = rightRotate(root);
}
else // If key is greater
{
// Insert in right subtree
root->right = insert(root->right, key);
// Fix Heap property if it is violated
if (root->right->priority > root->priority)
root = leftRotate(root);
}
return root;
}
/* Recursive implementation of Delete() */
TreapNode* deleteNode(TreapNode* root, int key)
{
if (root == NULL)
return root;
if (key < root->key)
root->left = deleteNode(root->left, key);
else if (key > root->key)
root->right = deleteNode(root->right, key);
// IF KEY IS AT ROOT
// If left is NULL
else if (root->left == NULL)
{
TreapNode *temp = root->right;
delete (root);
root = temp; // Make right child as root
}
// If Right is NULL
else if (root->right == NULL)
{
TreapNode *temp = root->left;
delete (root);
root = temp; // Make left child as root
}
// If key is at root and both left and right are not NULL
else if (root->left->priority < root->right->priority)
{
root = leftRotate(root);
root->left = deleteNode(root->left, key);
}
else
{
root = rightRotate(root);
root->right = deleteNode(root->right, key);
}
return root;
}
// A utility function to print tree
void inorder(TreapNode* root)
{
if (root)
{
inorder(root->left);
cout << "key: " << root->key << " | priority: %d "
<< root->priority;
if (root->left)
cout << " | left child: " << root->left->key;
if (root->right)
cout << " | right child: " << root->right->key;
cout << endl;
inorder(root->right);
}
}
// Driver Program to test above functions
int main()
{
srand ( time (NULL));
struct TreapNode *root = NULL;
root = insert(root, 50);
root = insert(root, 30);
root = insert(root, 20);
root = insert(root, 40);
root = insert(root, 70);
root = insert(root, 60);
root = insert(root, 80);
cout << "Inorder traversal of the given tree " ;
inorder(root);
cout << "Delete 20" ;
root = deleteNode(root, 20);
cout << "Inorder traversal of the modified tree " ;
inorder(root);
cout << "Delete 30" ;
root = deleteNode(root, 30);
cout << "Inorder traversal of the modified tree " ;
inorder(root);
cout << "Delete 50" ;
root = deleteNode(root, 50);
cout << "Inorder traversal of the modified tree " ;
inorder(root);
TreapNode *res = search(root, 50);
(res == NULL)? cout << "50 Not Found " :
cout << "50 found" ;
return 0;
}


输出:

Inorder traversal of the given tree key: 20 | priority: %d 92 | right child: 50key: 30 | priority: %d 48 | right child: 40key: 40 | priority: %d 21key: 50 | priority: %d 73 | left child: 30 | right child: 60key: 60 | priority: %d 55 | right child: 70key: 70 | priority: %d 50 | right child: 80key: 80 | priority: %d 44Delete 20Inorder traversal of the modified tree key: 30 | priority: %d 48 | right child: 40key: 40 | priority: %d 21key: 50 | priority: %d 73 | left child: 30 | right child: 60key: 60 | priority: %d 55 | right child: 70key: 70 | priority: %d 50 | right child: 80key: 80 | priority: %d 44Delete 30Inorder traversal of the modified tree key: 40 | priority: %d 21key: 50 | priority: %d 73 | left child: 40 | right child: 60key: 60 | priority: %d 55 | right child: 70key: 70 | priority: %d 50 | right child: 80key: 80 | priority: %d 44Delete 50Inorder traversal of the modified tree key: 40 | priority: %d 21key: 60 | priority: %d 55 | left child: 40 | right child: 70key: 70 | priority: %d 50 | right child: 80key: 80 | priority: %d 4450 Not Found 

对上述输出的解释:

Every node is written as key(priority)The above code constructs below tree  20(92)          50(73)     /       30(48)   60(55)                40(21)     70(50)                                80(44)   After deleteNode(20)     50(73)     /       30(48)   60(55)                40(21)     70(50)                                80(44)    After deleteNode(30)     50(73)     /       40(21)   60(55)                           70(50)                              80(44)    After deleteNode(50)     60(55)     /       40(21)  70(50)                           80(44)   

幸亏 贾伊·戈亚尔 用于提供初始实施。如果您发现任何不正确的地方,或者您想分享有关上述主题的更多信息,请写下评论。

© 版权声明
THE END
喜欢就支持一下吧
点赞15 分享