Floor and Ceil from a BST

Given a binary tree and a key(node) value, find the floor and ceil value for that particular key value.

Floor Value Node: Node with greatest data lesser than or equal to key value.
Ceil Value Node: Node with smallest data larger than or equal to key value.

For example, Let’s consider the Binary Tree below –

          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 floor / ceil value of a key in a binary search tree or sorted array. For example, consider designing memory management system in which free nodes are arranged in BST. Find the best fit for the input request.

Algorithm:



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.

Here is the code for ceil value:

C++

filter_none

edit
close

play_arrow

link
brightness_4
code

// Program to find ceil of a given value in BST
#include <bits/stdc++.h>
using namespace std;
  
/* A binary tree node has key, left child and right child */
class node {
public:
    int key;
    node* left;
    node* right;
};
  
/* Helper function that allocates a new node with the given key and 
NULL left and right pointers.*/
node* newNode(int key)
{
    node* Node = new node();
    Node->key = key;
    Node->left = NULL;
    Node->right = NULL;
    return (Node);
}
  
// Function to find ceil of a given input in BST. If input is more
// than the max key in BST, return -1
int Ceil(node* root, int input)
{
    // Base case
    if (root == NULL)
        return -1;
  
    // We found equal key
    if (root->key == input)
        return root->key;
  
    // If root's key is smaller, ceil must be in right subtree
    if (root->key < input)
        return Ceil(root->right, input);
  
    // Else, either left subtree or root has the ceil value
    int ceil = Ceil(root->left, input);
    return (ceil >= input) ? ceil : root->key;
}
  
// Driver program to test above function
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;
}
  
// This code is contributed by rathbhupendra

chevron_right


C

filter_none

edit
close

play_arrow

link
brightness_4
code

// Program to find ceil of a given value in BST
#include <stdio.h>
#include <stdlib.h>
  
/* A binary tree node has key, left child and right child */
struct node {
    int key;
    struct node* left;
    struct node* right;
};
  
/* Helper function that allocates a new node with the given key and
NULL left and right pointers.*/
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);
}
  
// Function to find ceil of a given input in BST. If input is more
// than the max key in BST, return -1
int Ceil(struct node* root, int input)
{
    // Base case
    if (root == NULL)
        return -1;
  
    // We found equal key
    if (root->key == input)
        return root->key;
  
    // If root's key is smaller, ceil must be in right subtree
    if (root->key < input)
        return Ceil(root->right, input);
  
    // Else, either left subtree or root has the ceil value
    int ceil = Ceil(root->left, input);
    return (ceil >= input) ? ceil : root->key;
}
  
// Driver program to test above function
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;
}

chevron_right


Java

filter_none

edit
close

play_arrow

link
brightness_4
code

// Java program to find ceil of a given value in BST
  
class Node {
  
    int data;
    Node left, right;
  
    Node(int d)
    {
        data = d;
        left = right = null;
    }
}
  
class BinaryTree {
  
    Node root;
  
    // Function to find ceil of a given input in BST.
    // If input is more than the max key in BST,
    // return -1
    int Ceil(Node node, int input)
    {
  
        // Base case
        if (node == null) {
            return -1;
        }
  
        // We found equal key
        if (node.data == input) {
            return node.data;
        }
  
        // If root's key is smaller,
        // ceil must be in right subtree
        if (node.data < input) {
            return Ceil(node.right, input);
        }
  
        // Else, either left subtree or root
        // has the ceil value
        int ceil = Ceil(node.left, input);
  
        return (ceil >= input) ? ceil : node.data;
    }
  
    // Driver Code
    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));
        }
    }
}
  
// This code has been contributed by Mayank Jaiswal

chevron_right


Python

filter_none

edit
close

play_arrow

link
brightness_4
code

# Python program to find ceil of a given value in BST
  
# A Binary tree node
class Node:
      
    # Constructor to create a new node
    def __init__(self, data):
        self.key = data
        self.left = None
        self.right = None
  
# Function to find ceil of a given input in BST. If input
# is more than the max key in BST, return -1
def ceil(root, inp):
      
    # Base Case
    if root == None:
        return -1
      
    # We found equal key
    if root.key == inp :
        return root.key 
      
    # If root's key is smaller, ceil must be in right subtree
    if root.key < inp:
        return ceil(root.right, inp)
      
    # Else, either left subtre or root has the ceil value
    val = ceil(root.left, inp)
    return val if val >= inp else root.key 
  
# Driver program to test above function
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))
  
# This code is contributed by Nikhil Kumar Singh(nickzuck_007)

chevron_right


C#

filter_none

edit
close

play_arrow

link
brightness_4
code

using System;
  
// C# program to find ceil of a given value in BST
  
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;
  
    // Function to find ceil of a given input in BST. If input is more
    // than the max key in BST, return -1
    public virtual int Ceil(Node node, int input)
    {
  
        // Base case
        if (node == null) {
            return -1;
        }
  
        // We found equal key
        if (node.data == input) {
            return node.data;
        }
  
        // If root's key is smaller, ceil must be in right subtree
        if (node.data < input) {
            return Ceil(node.right, input);
        }
  
        // Else, either left subtree or root has the ceil value
        int ceil = Ceil(node.left, input);
        return (ceil >= input) ? ceil : node.data;
    }
  
    // Driver program to test the above functions
    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));
        }
    }
}
  
// This code is contributed by Shrikant13

chevron_right



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

Iterative Approach –

1. If tree is empty, i.e. root is null, 
   return back to calling function.
2. If current node address is not null, perform the following steps : 
     (a) If current node data matches with the key value - 
             We have found both our floor and ceil value. 
             Hence, we return back to calling function.
    (b) If data in 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 key value.
    (c) If data in 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 key value.
3. 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++

filter_none

edit
close

play_arrow

link
brightness_4
code

// Program to find floor and ceil of a given key in BST
#include <bits/stdc++.h>
using namespace std;
  
/* A binary tree node has key, left child and right child */
struct Node {
    int data;
    Node *left, *right;
  
    Node(int value)
    {
        data = value;
        left = right = NULL;
    }
};
  
// Helper function to find floor and ceil of a given key in BST
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;
}
  
// Display the floor and ceil of a given key in BST.
// If key is less than the min key in BST, floor will be -1;
// If key is more than the max key in BST, ceil will be -1;
void floorCeilBST(Node* root, int key)
{
  
    // Variables 'floor' and 'ceil' are passed by reference
    int floor = -1, ceil = -1;
  
    floorCeilBSTHelper(root, key, floor, ceil);
  
    cout << key << ' ' << floor << ' ' << ceil << '\n';
}
  
// Driver program to test above function
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;
}

chevron_right


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(N)
Space Complexity: O(1)

Exercise:

1. Modify above code to find floor value of input key in a binary search tree.

2. Write neat algorithm to find floor and ceil values in a sorted array. Ensure to handle all possible boundary conditions.

This article is contributed by Venki. If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above.

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.




My Personal Notes arrow_drop_up

Article Tags :
Practice Tags :


14


Please write to us at contribute@geeksforgeeks.org to report any issue with the above content.