Преемник предварительного заказа всех узлов в двоичном дереве поиска
Рассмотрим BST (двоичное дерево поиска), где дублирование недопустимо.
Данный ключ присутствует в BST. Задача состоит в том, чтобы найти его преемника предварительного заказа в этом BST, то есть задача состоит в том, чтобы найти ключ, который идет рядом с данным ключом, если мы применяем обход предварительного заказа на данном BST.
Пример:
Вставьте следующие ключи в BST в том же порядке: 51, 39, 31, 54, 92, 42, 21, 10, 26, 52, 36, 47, 82, 5, 62.
В итоге вы получите BST, как показано ниже:

Предварительный заказ : 51 39 31 21 10 5 26 36 42 47 54 52 92 82 62
===================================== Ключевой преемник предварительного заказа ===================================== 51 39 39 31 31 21 21 10 10 5 5 26 26 36 36 42 42 47 47 54 52 92 92 82 82 62 62 Не существуют.
Простой подход: простой и легкий способ решить эту проблему - применить обход предварительного заказа к данному BST и сохранить ключи BST в массиве. Затем найдите данный ключ в массиве. Если он существует, то его следующий ключ (который может не обязательно существовать) является его преемником предварительного заказа. Если данный ключ не существует в массиве, это означает, что данный ключ не существует в BST и, следовательно, для этого ключа не может быть никакого преемника предварительного заказа.
Но этот алгоритм имеет временную сложность O (n) . И пространственная сложность O (n), и, следовательно, это не лучший способ решения этой проблемы.
Эффективный подход : эффективный способ решения этой проблемы основан на следующих наблюдениях:
- Найдите узел в BST, содержащий данный ключ.
- Если его нет в BST, то для этого ключа не может быть никакого преемника предварительного заказа.
- Если он существует в BST, то для этого ключа может быть преемник предварительного заказа. Обратите внимание, что если ключ существует, то необязательно, чтобы он имел преемника для предварительного заказа. Это зависит от позиции данного ключа в BST.
- Если узел, содержащий данный ключ, имеет левый дочерний элемент, то его левый дочерний элемент является его преемником предварительного порядка.
- Если узел, содержащий данное, имеет правого, но не левого дочернего элемента, то его правый дочерний элемент является его преемником предварительного порядка.
- Если узел, содержащий данный ключ, является листом, тогда вам нужно найти его ближайшего предка, у которого есть правый дочерний элемент, и ключ этого предка больше, чем данный ключ, то есть вы должны искать его ближайшего предка в левом поддереве, из которого данное ключ существует. Далее два случая:
- Такой предок существует, если это так, то правый дочерний элемент этого предка является преемником предварительного заказа данного ключа.
- Такого предка не существует, если он существует, то для данного ключа не существует преемника для предварительного заказа.
Below is the implementation of the above approach :
C
// C program to find pre-Order successor// of a node in Binary Search Tree#include<stdio.h>#include<stdlib.h>// Declare a structurestruct Node{ // Key to be stored in BST int key; // Pointer to left child struct Node *left; // Pointer to the right child struct Node *right; // Pointer to parent struct Node *parent;};// This function inserts node in BSTstruct Node* insert(int key, struct Node *root, struct Node *parent){ // If root is NULL, insert key here if(!root) { // Allocate memory dynamically struct Node *node = (struct Node*)malloc(sizeof(struct Node)); // Validate malloc call if(node) { // Populate the object pointer to by // pointer named node node->key = key; node->left = node->right = NULL; node->parent = parent; // Return newly created node return node; } else // Malloc was not successful to satisfy our request, // given an appropriate message to the user printf("Could not allocate memory."); } // If this is a duplicate key then give a message to user else if(key == root->key) printf("Duplicates are not allowed in BST."); // If the key to be inserted is greater than the root"s // key then it will go to the right subtree of // the tree with current root else if(key > root->key) root->right = insert(key, root->right,root); // If the key to be inserted is smaller than the // root"s key then it will go to a left subtree of // the tree with current root else root->left = insert(key, root->left, root); // Return the root return root;}// This function searched for a given key in BSTstruct Node* search(int key, struct Node *root){ // Since the root is empty and hence key // does not exist in BST if(!root) return NULL; // Current root contains the given key, // so return current root else if( key == root->key) return root; // Key is greater than the root"s key and therefore // we will search for this key in the right subtree of // tree with root as current root because of all of the keys // which are greater than the root"s key exist in the right subtree else if(key > root->key) return search(key, root->right); // Key is smaller than the root"s key and therefore we will // search for this key in the left subtree of the tree with // root as the current root because of all of the keys which are // smaller than the root"s key exists in the left subtree // search tree in the left subtree else return search(key, root->left); }// This function returns the node that contains the// pre-order successor for the given keystruct Node* preOrderSuccessor(int key, struct Node *root){ // Search for a node in BST that contains the given key struct Node *node = search(key, root); // There is no node in BST that contains the given key, // give an appropriate message to user if(!node){ printf("%d do not exists in BST.
", key); return NULL; } // There exist a node in BST that contains the given key // Apply our observations if(node->left) // If left child of the node that contains the // given key exist then it is the pre-order // successor for the given key return node->left; else if(node->right) // If right but not left child of node that contains // the given key exist then it is the pre-order // successor for the given key return node->right; else { // Node containing the key has neither left nor right child // which means that it is leaf node. In this case we will search // for its nearest ancestor with right child which has a key // greater than the given key // Since node is a leaf node so its parent is guaranteed to exist struct Node *temp = node->parent; // Search for nearest ancestor with right child that has // key greater than the given key while(temp){ if(key < temp->key && temp->right) break; temp = temp->parent; } // If such an ancestor exist then right child of this ancestor // is the pre-order successor for the given otherwise there // do not exist any pre-order successor for the given key return temp ? temp->right : NULL; }}// This function traverse the BST in pre-order fashionvoid preOrder(struct Node *root){ if(root) { // First visit the root printf("%d ", root->key); // Next visit its left subtree preOrder(root->left); // Finally visit its right subtree preOrder(root->right); }}// Driver codeint main(){ // Declares a root for our BST struct Node *ROOT = NULL; // We will create 15 random integers in // range 0-99 to populate our BST int a[] = {51, 39, 31, 54, 92, 42, 21, 10, 26, 52, 36, 47, 82, 5, 62}; int n = sizeof(a) / sizeof(a[0]); // Insert all elements into BST for(int i = 0 ; i < n; i++) { // Insert the generated number in BST printf("Inserting %2d.....", a[i]); ROOT = insert(a[i], ROOT, NULL); printf("Finished Insertion.
"); } // Apply pre-order traversal on BST printf("
Pre-Order Traversal : "); preOrder(ROOT); // Display pre-order Successors for all of the keys in BST printf("
====================================="); printf("
%-10s%s
", "Key", "Pre-Order Successor"); printf("=====================================
"); // This stores the pre-order successor for a given key struct Node *successor = NULL; // Iterate through all of the elements inserted // in BST to get their pre-order successor for(int i = 0 ; i < n; ++i) { // Get the pre-order successor for the given key successor = preOrderSuccessor(a[i], ROOT); if(successor) // Successor is not NULL and hence it contains // the pre-order successor for given key printf("%-10d%d
", a[i], successor->key); else // Successor is NULL and hence given key do // not have a pre-order successor printf("%-10dDo Not Exist.
", a[i]); } return 0;} |
Java
// Java program to find pre-Order successor// of a node in Binary Search Treeimport java.util.*;class GFG{// Declare a structurestatic class Node{ // Key to be stored in BST int key; // Pointer to left child Node left; // Pointer to the right child Node right; // Pointer to parent Node parent;};// This function inserts node in BSTstatic Node insert(int key, Node root, Node parent){ // If root is null, insert key here if(root == null) { // Allocate memory dynamically Node node = new Node(); // Validate malloc call if(node != null) { // Populate the object pointer to by // pointer named node node.key = key; node.left = node.right = null; node.parent = parent; // Return newly created node return node; } else // Malloc was not successful to // satisfy our request, given // an appropriate message to the user System.out.printf("Could not allocate memory."); } // If this is a duplicate key then // give a message to user else if(key == root.key) System.out.printf("Duplicates are not" + " allowed in BST."); // If the key to be inserted is greater than // the root"s key then it will go to the // right subtree of the tree with current root else if(key > root.key) root.right = insert(key, root.right, root); // If the key to be inserted is smaller than the // root"s key then it will go to a left subtree // of the tree with current root else root.left = insert(key, root.left, root); // Return the root return root;}// This function searched for a given key in BSTstatic Node search(int key, Node root){ // Since the root is empty and hence // key does not exist in BST if(root == null) return null; // Current root contains the given key, // so return current root else if( key == root.key) return root; // Key is greater than the root"s key and // therefore we will search for this key // in the right subtree of tree with root // as current root because of all of the keys // which are greater than the root"s key // exist in the right subtree else if(key > root.key) return search(key, root.right); // Key is smaller than the root"s key and // therefore we will search for this key // in the left subtree of the tree with root // as the current root because of all of the keys // which are smaller than the root"s key exists in // the left subtree search tree in the left subtree else return search(key, root.left);}// This function returns the node// that contains the pre-order successor// for the given keystatic Node preOrderSuccessor(int key, Node root){ // Search for a node in BST // that contains the given key Node node = search(key, root); // There is no node in BST // that contains the given key, // give an appropriate message to user if(node == null) { System.out.printf("%d do not exists" + " in BST.
", key); return null; } // There exist a node in BST that contains // the given key. Apply our observations if(node.left != null) <
РЕКОМЕНДУЕМЫЕ СТАТЬИ |