# Octree | Insertion and Searching

• Difficulty Level : Hard
• Last Updated : 19 Jul, 2022

Octree is a tree data structure in which each internal node can have at most 8 children. Like Binary tree which divides the space two segments, Octree divides the space into at most eight-part which is called as octanes. It is used to store the 3-D point which takes a large amount of space. If all the internal node of the Octree contains exactly 8 children, then it is called full Octree. It is also useful for high-resolution graphics like 3D computer graphics.

The Octree can be formed from 3D volume by doing the following steps:

1. Divide the current 3D volume into eight boxes
2. If any box has more than one point then divide it further into boxes
3. Do not divide the box which has one or zero points in it
4. Do this process repeatedly until all the box contains one or zero point in it

The above steps are shown in figure.

If S is the number of points in each dimension then the number of nodes that are formed in Octree is given by this formula

### Insertion in Octree:

• To insert a node in Octree, first of all, we check if a node exists or not if a node exists then return otherwise we go recursively
• First, we start with the root node and mark it as current
• Then we find the child node in which we can store the point
• If the node is empty then it is replaced with the node we want to insert and make it a leaf node
• If the node is the leaf node then make it an internal node and if it is an internal node then go to the child node, This process is performed recursively until an empty node is not found
• The time complexity of this function is where, N is the number of nodes

### Search in Octree:

• This function is used to search the point exist is the tree or not
• Start with the root node and search recursively if the node with given point found then return true, if an empty node or boundary point or empty point is encountered then return false
• If an internal node is found go that node. The time complexity of this function is also O(Log N) where, N is the number of nodes

Below is the implementation of the above approach

## CPP14

 `// Implementation of Octree in c++``#include ``#include ``using` `namespace` `std;` `#define TopLeftFront 0``#define TopRightFront 1``#define BottomRightFront 2``#define BottomLeftFront 3``#define TopLeftBottom 4``#define TopRightBottom 5``#define BottomRightBack 6``#define BottomLeftBack 7` `// Structure of a point``struct` `Point {``    ``int` `x;``    ``int` `y;``    ``int` `z;``    ``Point()``        ``: x(-1), y(-1), z(-1)``    ``{``    ``}` `    ``Point(``int` `a, ``int` `b, ``int` `c)``        ``: x(a), y(b), z(c)``    ``{``    ``}``};` `// Octree class``class` `Octree {` `    ``// if point == NULL, node is internal node.``    ``// if point == (-1, -1, -1), node is empty.``    ``Point* point;` `    ``// Represent the boundary of the cube``    ``Point *topLeftFront, *bottomRightBack;``    ``vector children;` `public``:``    ``// Constructor``    ``Octree()``    ``{``        ``// To declare empty node``        ``point = ``new` `Point();``    ``}` `    ``// Constructor with three arguments``    ``Octree(``int` `x, ``int` `y, ``int` `z)``    ``{``        ``// To declare point node``        ``point = ``new` `Point(x, y, z);``    ``}` `    ``// Constructor with six arguments``    ``Octree(``int` `x1, ``int` `y1, ``int` `z1, ``int` `x2, ``int` `y2, ``int` `z2)``    ``{``        ``// This use to construct Octree``        ``// with boundaries defined``        ``if` `(x2 < x1``            ``|| y2 < y1``            ``|| z2 < z1) {``            ``cout << ``"boundary points are not valid"` `<< endl;``            ``return``;``        ``}` `        ``point = nullptr;``        ``topLeftFront``            ``= ``new` `Point(x1, y1, z1);``        ``bottomRightBack``            ``= ``new` `Point(x2, y2, z2);` `        ``// Assigning null to the children``        ``children.assign(8, nullptr);``        ``for` `(``int` `i = TopLeftFront;``             ``i <= BottomLeftBack;``             ``++i)``            ``children[i] = ``new` `Octree();``    ``}` `    ``// Function to insert a point in the octree``    ``void` `insert(``int` `x,``                ``int` `y,``                ``int` `z)``    ``{` `        ``// If the point already exists in the octree``        ``if` `(find(x, y, z)) {``            ``cout << ``"Point already exist in the tree"` `<< endl;``            ``return``;``        ``}` `        ``// If the point is out of bounds``        ``if` `(x < topLeftFront->x``            ``|| x > bottomRightBack->x``            ``|| y < topLeftFront->y``            ``|| y > bottomRightBack->y``            ``|| z < topLeftFront->z``            ``|| z > bottomRightBack->z) {``            ``cout << ``"Point is out of bound"` `<< endl;``            ``return``;``        ``}` `        ``// Binary search to insert the point``        ``int` `midx = (topLeftFront->x``                    ``+ bottomRightBack->x)``                   ``/ 2;``        ``int` `midy = (topLeftFront->y``                    ``+ bottomRightBack->y)``                   ``/ 2;``        ``int` `midz = (topLeftFront->z``                    ``+ bottomRightBack->z)``                   ``/ 2;` `        ``int` `pos = -1;` `        ``// Checking the octant of``        ``// the point``        ``if` `(x <= midx) {``            ``if` `(y <= midy) {``                ``if` `(z <= midz)``                    ``pos = TopLeftFront;``                ``else``                    ``pos = TopLeftBottom;``            ``}``            ``else` `{``                ``if` `(z <= midz)``                    ``pos = BottomLeftFront;``                ``else``                    ``pos = BottomLeftBack;``            ``}``        ``}``        ``else` `{``            ``if` `(y <= midy) {``                ``if` `(z <= midz)``                    ``pos = TopRightFront;``                ``else``                    ``pos = TopRightBottom;``            ``}``            ``else` `{``                ``if` `(z <= midz)``                    ``pos = BottomRightFront;``                ``else``                    ``pos = BottomRightBack;``            ``}``        ``}` `        ``// If an internal node is encountered``        ``if` `(children[pos]->point == nullptr) {``            ``children[pos]->insert(x, y, z);``            ``return``;``        ``}` `        ``// If an empty node is encountered``        ``else` `if` `(children[pos]->point->x == -1) {``            ``delete` `children[pos];``            ``children[pos] = ``new` `Octree(x, y, z);``            ``return``;``        ``}``        ``else` `{``            ``int` `x_ = children[pos]->point->x,``                ``y_ = children[pos]->point->y,``                ``z_ = children[pos]->point->z;``            ``delete` `children[pos];``            ``children[pos] = nullptr;``            ``if` `(pos == TopLeftFront) {``                ``children[pos] = ``new` `Octree(topLeftFront->x,``                                           ``topLeftFront->y,``                                           ``topLeftFront->z,``                                           ``midx,``                                           ``midy,``                                           ``midz);``            ``}` `            ``else` `if` `(pos == TopRightFront) {``                ``children[pos] = ``new` `Octree(midx + 1,``                                           ``topLeftFront->y,``                                           ``topLeftFront->z,``                                           ``bottomRightBack->x,``                                           ``midy,``                                           ``midz);``            ``}``            ``else` `if` `(pos == BottomRightFront) {``                ``children[pos] = ``new` `Octree(midx + 1,``                                           ``midy + 1,``                                           ``topLeftFront->z,``                                           ``bottomRightBack->x,``                                           ``bottomRightBack->y,``                                           ``midz);``            ``}``            ``else` `if` `(pos == BottomLeftFront) {``                ``children[pos] = ``new` `Octree(topLeftFront->x,``                                           ``midy + 1,``                                           ``topLeftFront->z,``                                           ``midx,``                                           ``bottomRightBack->y,``                                           ``midz);``            ``}``            ``else` `if` `(pos == TopLeftBottom) {``                ``children[pos] = ``new` `Octree(topLeftFront->x,``                                           ``topLeftFront->y,``                                           ``midz + 1,``                                           ``midx,``                                           ``midy,``                                           ``bottomRightBack->z);``            ``}``            ``else` `if` `(pos == TopRightBottom) {``                ``children[pos] = ``new` `Octree(midx + 1,``                                           ``topLeftFront->y,``                                           ``midz + 1,``                                           ``bottomRightBack->x,``                                           ``midy,``                                           ``bottomRightBack->z);``            ``}``            ``else` `if` `(pos == BottomRightBack) {``                ``children[pos] = ``new` `Octree(midx + 1,``                                           ``midy + 1,``                                           ``midz + 1,``                                           ``bottomRightBack->x,``                                           ``bottomRightBack->y,``                                           ``bottomRightBack->z);``            ``}``            ``else` `if` `(pos == BottomLeftBack) {``                ``children[pos] = ``new` `Octree(topLeftFront->x,``                                           ``midy + 1,``                                           ``midz + 1,``                                           ``midx,``                                           ``bottomRightBack->y,``                                           ``bottomRightBack->z);``            ``}``            ``children[pos]->insert(x_, y_, z_);``            ``children[pos]->insert(x, y, z);``        ``}``    ``}` `    ``// Function that returns true if the point``    ``// (x, y, z) exists in the octree``    ``bool` `find(``int` `x, ``int` `y, ``int` `z)``    ``{``        ``// If point is out of bound``        ``if` `(x < topLeftFront->x``            ``|| x > bottomRightBack->x``            ``|| y < topLeftFront->y``            ``|| y > bottomRightBack->y``            ``|| z < topLeftFront->z``            ``|| z > bottomRightBack->z)``            ``return` `0;` `        ``// Otherwise perform binary search``        ``// for each ordinate``        ``int` `midx = (topLeftFront->x``                    ``+ bottomRightBack->x)``                   ``/ 2;``        ``int` `midy = (topLeftFront->y``                    ``+ bottomRightBack->y)``                   ``/ 2;``        ``int` `midz = (topLeftFront->z``                    ``+ bottomRightBack->z)``                   ``/ 2;` `        ``int` `pos = -1;` `        ``// Deciding the position``        ``// where to move``        ``if` `(x <= midx) {``            ``if` `(y <= midy) {``                ``if` `(z <= midz)``                    ``pos = TopLeftFront;``                ``else``                    ``pos = TopLeftBottom;``            ``}``            ``else` `{``                ``if` `(z <= midz)``                    ``pos = BottomLeftFront;``                ``else``                    ``pos = BottomLeftBack;``            ``}``        ``}``        ``else` `{``            ``if` `(y <= midy) {``                ``if` `(z <= midz)``                    ``pos = TopRightFront;``                ``else``                    ``pos = TopRightBottom;``            ``}``            ``else` `{``                ``if` `(z <= midz)``                    ``pos = BottomRightFront;``                ``else``                    ``pos = BottomRightBack;``            ``}``        ``}` `        ``// If an internal node is encountered``        ``if` `(children[pos]->point == nullptr) {``            ``return` `children[pos]->find(x, y, z);``        ``}` `        ``// If an empty node is encountered``        ``else` `if` `(children[pos]->point->x == -1) {``            ``return` `0;``        ``}``        ``else` `{` `            ``// If node is found with``            ``// the given value``            ``if` `(x == children[pos]->point->x``                ``&& y == children[pos]->point->y``                ``&& z == children[pos]->point->z)``                ``return` `1;``        ``}``        ``return` `0;``    ``}``};` `// Driver code``int` `main()``{``    ``Octree tree(1, 1, 1, 5, 5, 5);` `    ``tree.insert(1, 2, 3);``    ``tree.insert(1, 2, 3);``    ``tree.insert(6, 5, 5);` `    ``cout << (tree.find(1, 2, 3)``                 ``? ``"Found\n"``                 ``: ``"Not Found\n"``);` `    ``cout << (tree.find(3, 4, 4)``                 ``? ``"Found\n"``                 ``: ``"Not Found\n"``);``    ``tree.insert(3, 4, 4);` `    ``cout << (tree.find(3, 4, 4)``                 ``? ``"Found\n"``                 ``: ``"Not Found\n"``);` `    ``return` `0;``}`

Output:

```Point already exist in the tree
Point is out of bound
found