Deletion in a Binary Search Tree

In this video, we will see how deletion operation is performed in a binary search tree. This video will explain you the cases involved in binary search deletion.

#data-science #developer

What is GEEK

Buddha Community

Deletion in a Binary Search Tree
Osiki  Douglas

Osiki Douglas

1625122494

Binary Search in Python (Recursive and Iterative)

Searching for an element’s presence in a list is usually done using linear search and binary search. Linear search is time-consuming and memory expensive but is the simplest way to search for an element. On the other hand, Binary search is effective mainly due to the reduction of list dimension with each recursive function call or iteration. A practical implementation of binary search is autocompletion.

Python Binary Search Algorithm:

The objective of this project is to create a simple python program to implement binary search. It can be implemented in two ways: recursive (function calls) and iterative.

Project Prerequisites:

The project uses loops and functions to implement the search function. Hence good knowledge of python loops and function calls is sufficient to understand the code flow.

#python tutorials #binary search python #binary search python program #iterative binary search python #recursive binary search python

Brain  Crist

Brain Crist

1596650400

Count of Array elements greater than all elements on its left

Given an array A[ ] consisting of N distinct integers, the task is to find the number of elements which are **strictly greater **than all the elements preceding it and strictly greater than at least K elements on its right.

Examples:

Input:_ A[] = {2, 5, 1, 7, 3, 4, 0}, K = 3_

Output:_ 2_

Explanation:

The only array elements satisfying the given conditions are:

  • 5: Greater than all elements on its left {2} and at least K(= 3) elements on its right {1, 3, 4, 0}
  • 7: Greater than all elements on its left {2, 5, 1} and at least K(= 3) elements on its right {3, 4, 0}

Therefore, the count is 2.

Input:_ A[] = {11, 2, 4, 7, 5, 9, 6, 3}, K = 2_

Output:_ 1_

Naive Approach:

The simplest approach to solve the problem is to traverse the array and for each element, traverse all the elements on its left and check if all of them are smaller than it or not and traverse all elements on its right to check if at least K elements are smaller than it or not. For every element satisfying the conditions, increase count. Finally, print the value of count.

Time Complexity:_ O(N2)_

Auxiliary Space:_ O(1)_

Efficient Approach:

The above approach can be further optimized by using Self-Balancing BST. Follow the steps below:

  • Traverse the array from right to left and insert all elements one by one in an AVL Tree
  • Using the AVL Tree generate an array countSmaller[] which contains the count of smaller elements on the right of every array element.
  • Traverse the array and for every ith element, check if it is the maximum obtained so far and countSmaller[i] is greater than or equal to K.
  • If so, increase count.
  • Print the final value of count as the answer.

Below is the implementation of the above approach:

  • C++

// C++ Program to implement

// the above appraoch

#include <bits/stdc++.h>

**using** **namespace** std;

// Structure of an AVL Tree Node

**struct** node {

**int** key;

**struct** node* left;

**struct** node* right;

**int** height;

// Size of the tree rooted

// with this node

**int** size;

};

// Utility function to get maximum

// of two integers

**int** max(``**int** a, **int** b);

// Utility function to get height

// of the tree rooted with N

**int** height(``**struct** node* N)

{

**if** (N == NULL)

**return** 0;

**return** N->height;

}

// Utility function to find size of

// the tree rooted with N

**int** size(``**struct** node* N)

{

**if** (N == NULL)

**return** 0;

**return** N->size;

}

// Utility function to get maximum

// of two integers

**int** max(``**int** a, **int** b)

{

**return** (a > b) ? a : b;

}

// Helper function to allocates a

// new node with the given key

**struct** node* newNode(``**int** key)

{

**struct** node* node

= (``**struct** node*)

**malloc**``(``**sizeof**``(``**struct** node));

node->key = key;

node->left = NULL;

node->right = NULL;

node->height = 1;

node->size = 1;

**return** (node);

}

// Utility function to right rotate

// subtree rooted with y

**struct** node* rightRotate(``**struct** node* y)

{

**struct** node* x = y->left;

**struct** node* T2 = x->right;

// Perform rotation

x->right = y;

y->left = T2;

// Update heights

y->height = max(height(y->left),

height(y->right))

+ 1;

x->height = max(height(x->left),

height(x->right))

+ 1;

// Update sizes

y->size = size(y->left)

+ size(y->right) + 1;

x->size = size(x->left)

+ size(x->right) + 1;

// Return new root

**return** x;

}

// Utility function to left rotate

// subtree rooted with x

**struct** node* leftRotate(``**struct** node* x)

{

**struct** node* y = x->right;

**struct** node* T2 = y->left;

// Perform rotation

y->left = x;

x->right = T2;

// Update heights

x->height = max(height(x->left),

height(x->right))

+ 1;

y->height = max(height(y->left),

height(y->right))

+ 1;

// Update sizes

x->size = size(x->left)

+ size(x->right) + 1;

y->size = size(y->left)

+ size(y->right) + 1;

// Return new root

**return** y;

}

// Function to obtain Balance factor

// of node N

**int** getBalance(``**struct** node* N)

{

**if** (N == NULL)

**return** 0;

**return** height(N->left)

- height(N->right);

}

// Function to insert a new key to the

// tree rooted with node

**struct** node* insert(``**struct** node* node, **int** key,

**int**``* count)

{

// Perform the normal BST rotation

**if** (node == NULL)

**return** (newNode(key));

**if** (key < node->key)

node->left

= insert(node->left, key, count);

**else** {

node->right

= insert(node->right, key, count);

// Update count of smaller elements

*count = *count + size(node->left) + 1;

}

// Update height and size of the ancestor

node->height = max(height(node->left),

height(node->right))

+ 1;

node->size = size(node->left)

+ size(node->right) + 1;

// Get the balance factor of the ancestor

**int** balance = getBalance(node);

// Left Left Case

**if** (balance > 1 && key < node->left->key)

**return** rightRotate(node);

// Right Right Case

**if** (balance < -1 && key > node->right->key)

**return** leftRotate(node);

// Left Right Case

**if** (balance > 1 && key > node->left->key) {

node->left = leftRotate(node->left);

**return** rightRotate(node);

}

// Right Left Case

**if** (balance < -1 && key < node->right->key) {

node->right = rightRotate(node->right);

**return** leftRotate(node);

}

**return** node;

}

// Function to generate an array which contains

// count of smaller elements on the right

**void** constructLowerArray(``**int** arr[],

**int** countSmaller[],

**int** n)

{

**int** i, j;

**struct** node* root = NULL;

**for** (i = 0; i < n; i++)

countSmaller[i] = 0;

// Insert all elements in the AVL Tree

// and get the count of smaller elements

**for** (i = n - 1; i >= 0; i--) {

root = insert(root, arr[i],

&countSmaller[i]);

}

}

// Function to find the number

// of elements which are greater

// than all elements on its left

// and K elements on its right

**int** countElements(``**int** A[], **int** n, **int** K)

{

**int** count = 0;

// Stores the count of smaller

// elements on its right

**int**``* countSmaller

= (``**int**``*)``**malloc**``(``**sizeof**``(``**int**``) * n);

constructLowerArray(A, countSmaller, n);

**int** maxi = INT_MIN;

**for** (``**int** i = 0; i <= (n - K - 1); i++) {

**if** (A[i] > maxi && countSmaller[i] >= K) {

count++;

maxi = A[i];

}

}

**return** count;

}

// Driver Code

**int** main()

{

**int** A[] = { 2, 5, 1, 7, 3, 4, 0 };

**int** n = **sizeof**``(A) / **sizeof**``(``**int**``);

**int** K = 3;

cout << countElements(A, n, K);

**return** 0;

}

Output:

2

_Time Complexity: _O(NlogN)

_Auxiliary Space: _O(N)

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.

#advanced data structure #arrays #binary search tree #mathematical #searching #avl-tree #balanced binary search trees #rotation

Check if all the Nodes in a Binary Tree having common values are at least D distance apart

Given a Binary Tree and an integer D, the task is to check if the distance between all pairs of same node values in the Tree is ? D or not. If found to be true, then print Yes. Otherwise, print No.

Examples:

Input:_ D = 7 _

                1
              /   \ 
             2     3
            / \   /  \ 
           4   3  4   4

Output:_ Yes _

Explanation:

_The repeated value of nodes are 3 and 4. _

_The distance between the two nodes valued 3, is 3. _

_The maximum distance between any pair of nodes valued 4 is 4. _

Therefore, none of the distances exceed 7

Input:_ D = 1 _

          3
         / \
        3   3
             \
              3

Output:_ No _

Recommended: Please try your approach on {IDE} first, before moving on to the solution.

**Approach: **

The idea is to observe that the problem is similar to finding the distance between two nodes of a tree. But there can be multiple pairs of nodes for which we have to find the distance. Follow the steps below:

  1. Perform the Post Order Traversal of the given tree and find the distance between the repeated pairs of nodes.
  2. Find the nodes that are repeated in the tree using unordered_map.
  3. For each repeated node of a particular value, find the maximum possible distance between any pair.
  4. If that distance is > D, print “No”.
  5. If no such node value is found having a pair containing that value, exceeding **D, **then print “Yes”.

#greedy #recursion #searching #tree #binary tree #frequency-counting #postorder traversal #tree-traversal

Deletion in Binary Search Tree with JavaScript

Prerequisite: Binary Search Tree In JavaScript


Binary Search Tree Example

Deletion in binary search tree can be tricky, since we’re not working with just leafs but having to restructure all of a node’s children.

Deletion in Binary Search Tree has been divided into 3 cases:

  • Node to be deleted is leaf. To delete a leaf node, simply remove it from the tree. Since it was a leaf node we deleted it from the tree without making any other changes.

Remove leaf

  • Node to be deleted has only one child. To delete this node, copy the child to the node and delete the child. The node had only one child so we copied its child’s value to it and deleted its child.

Remove node with one child

  • Node to be deleted has two children. First, find in-order successor of the node. Now copy contents of the in-order successor to the node and delete the in-order successor. The in-order predecessor can also be used in the same manner.

Remove node with two children

#algorithms #deletion #javascript #data-structures #binary-search-tree #programming

Insert into a Binary Search Tree — Day 12(Python)

Today we will be discussing one of the leetcode’s October daily coding challenge questions.
Before I jump into the problem, we need to understand a few features of Binary Search Tree.
A binary search tree is a tree-like data structure with added features as follows.
The subtree to the left side of the root node will always be lesser than the root node.
The subtree to the right side of the root node will always be greater than the root node.
The left and right subtree of the root node must be a Binary Search Tree

#python #coding #leetcode-medium #binary-search-tree #binary search