Floor and Ceil from a BST
Given a binary search tree and a key(node) value, find the floor and ceil value for that particular key value.
- Floor Value Node: Node with the greatest data lesser than or equal to the key value.
- Ceil Value Node: Node with the smallest data larger than or equal to the key value.
Example:
8
/ \
4 12
/ \ / \
2 6 10 14
Key: 11 Floor: 10 Ceil: 12
Key: 1 Floor: -1 Ceil: 2
Key: 6 Floor: 6 Ceil: 6
Key: 15 Floor: 14 Ceil: -1
There are numerous applications where we need to find the floor/ceil value of a key in a binary search tree or sorted array. For example, consider designing a memory management system in which free nodes are arranged in BST. Find the best fit for the input request.
Ceil in Binary Search Tree using Recursion:
To solve the problem follow the below idea:
Imagine we are moving down the tree, and assume we are root node.
The comparison yields three possibilities,
A) Root data is equal to key. We are done, root data is ceil value.
B) Root data < key value, certainly the ceil value can’t be in left subtree.
Proceed to search on right subtree as reduced problem instance.
C) Root data > key value, the ceil value may be in left subtree.
We may find a node with is larger data than key value in left subtree,
if not the root itself will be ceil node.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
class node {
public :
int key;
node* left;
node* right;
};
node* newNode( int key)
{
node* Node = new node();
Node->key = key;
Node->left = NULL;
Node->right = NULL;
return (Node);
}
int Ceil(node* root, int input)
{
if (root == NULL)
return -1;
if (root->key == input)
return root->key;
if (root->key < input)
return Ceil(root->right, input);
int ceil = Ceil(root->left, input);
return ( ceil >= input) ? ceil : root->key;
}
int main()
{
node* root = newNode(8);
root->left = newNode(4);
root->right = newNode(12);
root->left->left = newNode(2);
root->left->right = newNode(6);
root->right->left = newNode(10);
root->right->right = newNode(14);
for ( int i = 0; i < 16; i++)
cout << i << " " << Ceil(root, i) << endl;
return 0;
}
|
C
#include <stdio.h>
#include <stdlib.h>
struct node {
int key;
struct node* left;
struct node* right;
};
struct node* newNode( int key)
{
struct node* node
= ( struct node*) malloc ( sizeof ( struct node));
node->key = key;
node->left = NULL;
node->right = NULL;
return (node);
}
int Ceil( struct node* root, int input)
{
if (root == NULL)
return -1;
if (root->key == input)
return root->key;
if (root->key < input)
return Ceil(root->right, input);
int ceil = Ceil(root->left, input);
return ( ceil >= input) ? ceil : root->key;
}
int main()
{
struct node* root = newNode(8);
root->left = newNode(4);
root->right = newNode(12);
root->left->left = newNode(2);
root->left->right = newNode(6);
root->right->left = newNode(10);
root->right->right = newNode(14);
for ( int i = 0; i < 16; i++)
printf ( "%d %d\n" , i, Ceil(root, i));
return 0;
}
|
Java
class Node {
int data;
Node left, right;
Node( int d)
{
data = d;
left = right = null ;
}
}
class BinaryTree {
Node root;
int Ceil(Node node, int input)
{
if (node == null ) {
return - 1 ;
}
if (node.data == input) {
return node.data;
}
if (node.data < input) {
return Ceil(node.right, input);
}
int ceil = Ceil(node.left, input);
return (ceil >= input) ? ceil : node.data;
}
public static void main(String[] args)
{
BinaryTree tree = new BinaryTree();
tree.root = new Node( 8 );
tree.root.left = new Node( 4 );
tree.root.right = new Node( 12 );
tree.root.left.left = new Node( 2 );
tree.root.left.right = new Node( 6 );
tree.root.right.left = new Node( 10 );
tree.root.right.right = new Node( 14 );
for ( int i = 0 ; i < 16 ; i++) {
System.out.println(i + " "
+ tree.Ceil(tree.root, i));
}
}
}
|
Python
class Node:
def __init__( self , data):
self .key = data
self .left = None
self .right = None
def ceil(root, inp):
if root = = None :
return - 1
if root.key = = inp:
return root.key
if root.key < inp:
return ceil(root.right, inp)
val = ceil(root.left, inp)
return val if val > = inp else root.key
if __name__ = = '__main__' :
root = Node( 8 )
root.left = Node( 4 )
root.right = Node( 12 )
root.left.left = Node( 2 )
root.left.right = Node( 6 )
root.right.left = Node( 10 )
root.right.right = Node( 14 )
for i in range ( 16 ):
print "% d % d" % (i, ceil(root, i))
|
C#
using System;
public class Node {
public int data;
public Node left, right;
public Node( int d)
{
data = d;
left = right = null ;
}
}
public class BinaryTree {
public static Node root;
public virtual int Ceil(Node node, int input)
{
if (node == null ) {
return -1;
}
if (node.data == input) {
return node.data;
}
if (node.data < input) {
return Ceil(node.right, input);
}
int ceil = Ceil(node.left, input);
return (ceil >= input) ? ceil : node.data;
}
public static void Main( string [] args)
{
BinaryTree tree = new BinaryTree();
BinaryTree.root = new Node(8);
BinaryTree.root.left = new Node(4);
BinaryTree.root.right = new Node(12);
BinaryTree.root.left.left = new Node(2);
BinaryTree.root.left.right = new Node(6);
BinaryTree.root.right.left = new Node(10);
BinaryTree.root.right.right = new Node(14);
for ( int i = 0; i < 16; i++) {
Console.WriteLine(i + " " + tree.Ceil(root, i));
}
}
}
|
Javascript
<script>
class Node
{
constructor(x) {
this .data = x;
this .left = null ;
this .right = null ;
}
}
let root;
function Ceil(node,input)
{
if (node == null ) {
return -1;
}
if (node.data == input) {
return node.data;
}
if (node.data < input) {
return Ceil(node.right, input);
}
let ceil = Ceil(node.left, input);
return (ceil >= input) ? ceil : node.data;
}
root = new Node(8)
root.left = new Node(4)
root.right = new Node(12)
root.left.left = new Node(2)
root.left.right = new Node(6)
root.right.left = new Node(10)
root.right.right = new Node(14)
for (let i = 0; i < 16; i++) {
document.write(i + " " + Ceil(root, i)+ "<br>" );
}
</script>
|
Output
0 2
1 2
2 2
3 4
4 4
5 6
6 6
7 8
8 8
9 10
10 10
11 12
12 12
13 14
14 14
15 -1
Time complexity: O(log N)
Auxiliary Space: O(log N)
Below is the implementation to find the floor value:
C++
#include <bits/stdc++.h>
using namespace std;
class node {
public :
int key;
node* left;
node* right;
};
node* newNode( int key)
{
node* Node = new node();
Node->key = key;
Node->left = NULL;
Node->right = NULL;
return (Node);
}
int Floor(node* root, int input)
{
if (root == NULL)
return -1;
if (root->key == input)
return root->key;
if (root->key > input)
return Floor(root->left, input);
else {
int floor = Floor(root->right, input);
return ( floor <= input && floor != -1) ? floor
: root->key;
}
}
int main()
{
node* root = newNode(8);
root->left = newNode(4);
root->right = newNode(12);
root->left->left = newNode(2);
root->left->right = newNode(6);
root->right->left = newNode(10);
root->right->right = newNode(14);
for ( int i = 0; i < 16; i++)
cout << i << " " << Floor(root, i) << endl;
return 0;
}
|
Java
class Node {
int data;
Node left, right;
Node( int d)
{
data = d;
left = right = null ;
}
}
class BinaryTree {
Node root;
int Floor(Node node, int input)
{
if (node == null ) {
return - 1 ;
}
if (node.data == input) {
return node.data;
}
if (node.data > input) {
return Floor(node.left, input);
}
else {
int floor = Floor(node.right, input);
return (floor <= input && floor != - 1 )
? floor
: node.data;
}
}
public static void main(String[] args)
{
BinaryTree tree = new BinaryTree();
tree.root = new Node( 8 );
tree.root.left = new Node( 4 );
tree.root.right = new Node( 12 );
tree.root.left.left = new Node( 2 );
tree.root.left.right = new Node( 6 );
tree.root.right.left = new Node( 10 );
tree.root.right.right = new Node( 14 );
for ( int i = 0 ; i < 16 ; i++) {
System.out.println(i + " "
+ tree.Floor(tree.root, i));
}
}
}
|
Python3
class Node:
def __init__( self , data):
self .key = data
self .left = None
self .right = None
def Floor(root, inp):
if root = = None :
return - 1
if root.key = = inp:
return root.key
if root.key > inp:
return Floor(root.left, inp)
else :
floor = Floor(root.right, inp)
return floor if floor < = inp and floor ! = - 1 else root.key
if __name__ = = '__main__' :
root = Node( 8 )
root.left = Node( 4 )
root.right = Node( 12 )
root.left.left = Node( 2 )
root.left.right = Node( 6 )
root.right.left = Node( 10 )
root.right.right = Node( 14 )
for i in range ( 16 ):
print (i, Floor(root, i))
|
C#
using System;
public class Node {
public int data;
public Node left, right;
public Node( int d)
{
data = d;
left = right = null ;
}
}
public class BinaryTree {
public static Node root;
public virtual int Floor(Node node, int input)
{
if (node == null ) {
return -1;
}
if (node.data == input) {
return node.data;
}
if (node.data > input) {
return Floor(node.left, input);
}
else {
int floor = Floor(node.right, input);
return (floor <= input && floor != -1)
? floor
: node.data;
}
}
public static void Main( string [] args)
{
BinaryTree tree = new BinaryTree();
BinaryTree.root = new Node(8);
BinaryTree.root.left = new Node(4);
BinaryTree.root.right = new Node(12);
BinaryTree.root.left.left = new Node(2);
BinaryTree.root.left.right = new Node(6);
BinaryTree.root.right.left = new Node(10);
BinaryTree.root.right.right = new Node(14);
for ( int i = 0; i < 16; i++) {
Console.WriteLine(i + " "
+ tree.Floor(root, i));
}
}
}
|
Javascript
class Node
{
constructor(x) {
this .data = x;
this .left = null ;
this .right = null ;
}
}
let root;
function Floor(root, input)
{
if (root == null )
return -1;
if (root.data == input)
return root.data;
if (root.data > input){
return Floor(root.left, input);
}
else {
let floor = Floor(root.right, input);
return (floor <= input && floor != -1) ? floor : root.data;
}
}
root = new Node(8)
root.left = new Node(4)
root.right = new Node(12)
root.left.left = new Node(2)
root.left.right = new Node(6)
root.right.left = new Node(10)
root.right.right = new Node(14)
for (let i = 0; i < 16; i++) {
console.log(i + " " + Floor(root, i));
}
|
Output
0 -1
1 -1
2 2
3 2
4 4
5 4
6 6
7 6
8 8
9 8
10 10
11 10
12 12
13 12
14 14
15 14
Time complexity: O(log N)
Auxiliary Space: O(log N)
The iterative approach to find the floor and ceil value in a BST:
To solve the problem follow the below steps:
- If the tree is empty, i.e. root is null, return back to the calling function.
- If the current node address is not null, perform the following steps :
- If the current node data matches with the key value – We have found both our floor and ceil value.
Hence, we return back to the calling function.
- If data in the current node is lesser than the key value – We assign the current node data to the variable keeping
track of current floor value and explore the right subtree, as it may contain nodes with values greater than the key value.
- If data in the current node is greater than the key value – We assign the current node data to the variable keeping track
of current ceil value and explore the left subtree, as it may contain nodes with values lesser than the key value.
- Once we reach null, we return back to the calling function, as we have got our required floor and ceil values for the particular key value.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
struct Node {
int data;
Node *left, *right;
Node( int value)
{
data = value;
left = right = NULL;
}
};
void floorCeilBSTHelper(Node* root, int key, int & floor ,
int & ceil )
{
while (root) {
if (root->data == key) {
ceil = root->data;
floor = root->data;
return ;
}
if (key > root->data) {
floor = root->data;
root = root->right;
}
else {
ceil = root->data;
root = root->left;
}
}
return ;
}
void floorCeilBST(Node* root, int key)
{
int floor = -1, ceil = -1;
floorCeilBSTHelper(root, key, floor , ceil );
cout << key << ' ' << floor << ' ' << ceil << '\n' ;
}
int main()
{
Node* root = new Node(8);
root->left = new Node(4);
root->right = new Node(12);
root->left->left = new Node(2);
root->left->right = new Node(6);
root->right->left = new Node(10);
root->right->right = new Node(14);
for ( int i = 0; i < 16; i++)
floorCeilBST(root, i);
return 0;
}
|
Java
import java.io.*;
class Node {
int data;
Node left, right;
Node( int d)
{
data = d;
left = right = null ;
}
}
class BinaryTree {
Node root;
int floor;
int ceil;
public void floorCeilBSTHelper(Node root, int key)
{
while (root != null ) {
if (root.data == key) {
ceil = root.data;
floor = root.data;
return ;
}
if (key > root.data) {
floor = root.data;
root = root.right;
}
else {
ceil = root.data;
root = root.left;
}
}
return ;
}
public void floorCeilBST(Node root, int key)
{
floor = - 1 ;
ceil = - 1 ;
floorCeilBSTHelper(root, key);
System.out.println(key + " " + floor + " " + ceil);
}
public static void main(String[] args)
{
BinaryTree tree = new BinaryTree();
tree.root = new Node( 8 );
tree.root.left = new Node( 4 );
tree.root.right = new Node( 12 );
tree.root.left.left = new Node( 2 );
tree.root.left.right = new Node( 6 );
tree.root.right.left = new Node( 10 );
tree.root.right.right = new Node( 14 );
for ( int i = 0 ; i < 16 ; i++) {
tree.floorCeilBST(tree.root, i);
}
}
}
|
Python3
class Node:
def __init__( self , x):
self .data = x
self .left = None
self .right = None
def floorCeilBSTHelper(root, key):
global floor, ceil
while (root):
if (root.data = = key):
ceil = root.data
floor = root.data
return
if (key > root.data):
floor = root.data
root = root.right
else :
ceil = root.data
root = root.left
def floorCeilBST(root, key):
global floor, ceil
floor = - 1
ceil = - 1
floorCeilBSTHelper(root, key)
print (key, floor, ceil)
if __name__ = = '__main__' :
floor, ceil = - 1 , - 1
root = Node( 8 )
root.left = Node( 4 )
root.right = Node( 12 )
root.left.left = Node( 2 )
root.left.right = Node( 6 )
root.right.left = Node( 10 )
root.right.right = Node( 14 )
for i in range ( 16 ):
floorCeilBST(root, i)
|
C#
using System;
public class Node {
public int data;
public Node left, right;
public Node( int d)
{
data = d;
left = right = null ;
}
}
public class BinaryTree {
public static Node root;
int floor;
int ceil;
public int floorCeilBSTHelper(Node root, int key)
{
while (root != null ) {
if (root.data == key) {
ceil = root.data;
floor = root.data;
return 0;
}
if (key > root.data) {
floor = root.data;
root = root.right;
}
else {
ceil = root.data;
root = root.left;
}
}
return 0;
}
public void floorCeilBST(Node root, int key)
{
floor = -1;
ceil = -1;
floorCeilBSTHelper(root, key);
Console.WriteLine(key + " " + floor + " " + ceil);
}
static public void Main()
{
BinaryTree tree = new BinaryTree();
BinaryTree.root = new Node(8);
BinaryTree.root.left = new Node(4);
BinaryTree.root.right = new Node(12);
BinaryTree.root.left.left = new Node(2);
BinaryTree.root.left.right = new Node(6);
BinaryTree.root.right.left = new Node(10);
BinaryTree.root.right.right = new Node(14);
for ( int i = 0; i < 16; i++) {
tree.floorCeilBST(BinaryTree.root, i);
}
}
}
|
Javascript
<script>
class Node
{
constructor(d)
{
this .data = d;
this .left = null ;
this .right = null ;
}
}
var root = null ;
var floor;
var ceil;
function floorCeilBSTHelper(root, key)
{
while (root != null )
{
if (root.data == key)
{
ceil = root.data;
floor = root.data;
return 0;
}
if (key > root.data)
{
floor = root.data;
root = root.right;
}
else
{
ceil = root.data;
root = root.left;
}
}
return 0;
}
function floorCeilBST(root, key)
{
floor = -1;
ceil = -1;
floorCeilBSTHelper(root, key);
document.write(key + " " + floor +
" " + ceil + "<br>" );
}
root = new Node(8);
root.left = new Node(4);
root.right = new Node(12);
root.left.left = new Node(2);
root.left.right = new Node(6);
root.right.left = new Node(10);
root.right.right = new Node(14);
for ( var i = 0; i < 16; i++)
{
floorCeilBST(root, i);
}
</script>
|
Output
0 -1 2
1 -1 2
2 2 2
3 2 4
4 4 4
5 4 6
6 6 6
7 6 8
8 8 8
9 8 10
10 10 10
11 10 12
12 12 12
13 12 14
14 14 14
15 14 -1
Time Complexity: O(log N)
Auxiliary Space: O(1)
Exercise:
- Modify the above code to find the floor value of the input key in a binary search tree.
- Write a neat algorithm to find floor and ceil values in a sorted array. Ensure to handle all possible boundary conditions.
Last Updated :
11 Jan, 2023
Like Article
Save Article
Share your thoughts in the comments
Please Login to comment...