Skip to content
geeksforgeeks
  • Courses
    • DSA to Development
    • Get IBM Certification
    • Newly Launched!
      • Master Django Framework
      • Become AWS Certified
    • For Working Professionals
      • Interview 101: DSA & System Design
      • Data Science Training Program
      • JAVA Backend Development (Live)
      • DevOps Engineering (LIVE)
      • Data Structures & Algorithms in Python
    • For Students
      • Placement Preparation Course
      • Data Science (Live)
      • Data Structure & Algorithm-Self Paced (C++/JAVA)
      • Master Competitive Programming (Live)
      • Full Stack Development with React & Node JS (Live)
    • Full Stack Development
    • Data Science Program
    • All Courses
  • Tutorials
    • Data Structures & Algorithms
    • ML & Data Science
    • Interview Corner
    • Programming Languages
    • Web Development
    • CS Subjects
    • DevOps And Linux
    • School Learning
  • Practice
    • Build your AI Agent
    • GfG 160
    • Problem of the Day
    • Practice Coding Problems
    • GfG SDE Sheet
  • Contests
    • Accenture Hackathon (Ending Soon!)
    • GfG Weekly [Rated Contest]
    • Job-A-Thon Hiring Challenge
    • All Contests and Events
  • DSA
  • Interview Problems on Tree
  • Practice Tree
  • MCQs on Tree
  • Tutorial on Tree
  • Types of Trees
  • Basic operations
  • Tree Traversal
  • Binary Tree
  • Complete Binary Tree
  • Ternary Tree
  • Binary Search Tree
  • Red-Black Tree
  • AVL Tree
  • Full Binary Tree
  • B-Tree
  • Advantages & Disadvantages
Open In App
Next Article:
Implementation of B-Tree in C
Next article icon

Implementation of compressed 2D Binary Indexed tree

Last Updated : 17 Oct, 2023
Comments
Improve
Suggest changes
Like Article
Like
Report

A compressed 2D Binary Indexed Tree (BIT) is a data structure that is used to efficiently store and query two-dimensional arrays, particularly when the values in the array are frequently updated.

The compressed 2D Binary Indexed Tree (BIT) is a data structure used for fast querying and updating values in a two-dimensional array. It is an extension of the Binary Indexed Tree that is used for one-dimensional arrays. In the compressed 2D BIT, each node in the binary tree represents the sum of a rectangular subregion of the two-dimensional array. This allows for efficient range queries and updates on the two-dimensional array.

To save memory, the compressed 2D BIT uses a compression technique that removes empty nodes from the binary tree. This results in a smaller tree and a smaller memory footprint, which makes it useful for applications where memory is limited. The compressed 2D BIT can be used in a variety of applications, including image processing, spatial data analysis, and computer graphics.

The implementation of 2D BIT consists of the following components:

  • Compress the array: The compressed 2D BIT stores the prefix sums of the compressed array, which is obtained by compressing the original array by mapping each unique element in the array to an index in the range [1, n], where n is the number of unique elements in the array. This compression reduces the memory usage of the BIT.
  • Build the BIT: The compressed 2D BIT can be built using a modified version of the 1D BIT algorithm. The BIT is built row by row, where each row is compressed before being processed. The prefix sum of each compressed row is computed using the BIT, and the resulting prefix sums are stored in the BIT.
  • Query the BIT: To query the compressed 2D BIT, the query range is compressed and then processed row by row using the BIT. The prefix sums of the compressed rows are summed to obtain the prefix sum of the query range.
  • Update the BIT: Updating the compressed 2D BIT involves compressing the updated element and then updating the prefix sums of the compressed rows that contain the updated element using the 1D BIT update algorithm.

To implement a compressed 2D Binary Indexed Tree, we can follow the following steps:

  • Create an n x m two-dimensional array and initialize it with zeros. This array will be used to store the values that you want to query or update.
  • Create an n x m two-dimensional array called the compressed BIT. Initialize this array with zeros.
  • To update a value in the two-dimensional array, add the value to the corresponding cell in the compressed BIT and all its ancestors in the tree. This can be done using the standard BIT update algorithm for one-dimensional arrays.
  • To query the sum of values in a rectangular subregion of the two-dimensional array, calculate the sum of the values in the compressed BIT for the four corners of the rectangle and subtract the sum of the values in the compressed BIT for the cells outside the rectangle. This can also be done using the standard BIT query algorithm for one-dimensional arrays.
  • To compress the 2D BIT, iterate through each row of the 2D BIT and remove any nodes that have a value of zero and whose two children are also zero. This reduces the memory footprint of the data structure.

Below is the Python code to implement the above steps:

C++
#include <bits/stdc++.h> using namespace std;  // Compressed2DBIT class class Compressed2DBIT {     int n, m;     vector<vector<int> > bit, tree;  public:     // Constructor     Compressed2DBIT(int n, int m)     {         this->n = n;         this->m = m;          // Initialize bit and tree vectors         bit.assign(n + 1, vector<int>(m + 1, 0));         tree.assign(n, vector<int>(m, 0));     }      // Update function for bit vector     void update(int x, int y, int val)     {         while (x <= n) {             int y1 = y;             while (y1 <= m) {                 bit[x][y1] += val;                 y1 += y1 & -y1;             }             x += x & -x;         }     }      // Query function for bit vector     int query(int x, int y)     {         int s = 0;         while (x > 0) {             int y1 = y;             while (y1 > 0) {                 s += bit[x][y1];                 y1 -= y1 & -y1;             }             x -= x & -x;         }         return s;     }      // Compresses the bit vector into a 2D tree     void compress()     {         for (int i = 1; i <= n; i++) {             for (int j = 1; j <= m; j++) {                 // Compute the sum of elements in the                 // corresponding rectangle                 tree[i - 1][j - 1] = query(i, j)                                      - query(i - 1, j)                                      - query(i, j - 1)                                      + query(i - 1, j - 1);             }         }         bit.clear(); // Clear bit vector after compression     }      // Getter function for compressed tree     vector<vector<int> > get_compressed_tree()     {         return tree;     } };  // Main function int main() {     // Initialize input matrix     vector<vector<int> > arr = { { 1, 2, 3, 4, 5 },                                  { 6, 7, 8, 9, 10 },                                  { 11, 12, 13, 14, 15 },                                  { 16, 17, 18, 19, 20 } };      // Create Compressed2DBIT object and update with input     // matrix     Compressed2DBIT bit(4, 5);     for (int i = 0; i < 4; i++) {         for (int j = 0; j < 5; j++) {             bit.update(i + 1, j + 1, arr[i][j]);         }     }      // Test query function     cout << bit.query(2, 3) << endl; // expected output: 27     cout << bit.query(4, 5) << endl; // expected output: 210      // Compress the bit vector and test query function again     bit.compress();     cout << bit.query(2, 3) << endl; // expected output: 27     cout << bit.query(4, 5) << endl; // expected output: 210      // Get compressed tree and print it     vector<vector<int> > compressed_tree         = bit.get_compressed_tree();     for (auto row : compressed_tree) {         for (auto x : row) {             cout << x << " ";         }         cout << endl;     }      return 0; } 
Java
import java.util.*;  // Compressed2DBIT class class Compressed2DBIT {     int n, m;     List<List<Integer>> bit, tree;      // Constructor     public Compressed2DBIT(int n, int m) {         this.n = n;         this.m = m;          // Initialize bit and tree lists         bit = new ArrayList<>(n + 1);         for (int i = 0; i <= n; i++) {             bit.add(new ArrayList<>(m + 1));             for (int j = 0; j <= m; j++) {                 bit.get(i).add(0);             }         }          tree = new ArrayList<>(n);         for (int i = 0; i < n; i++) {             tree.add(new ArrayList<>(m));             for (int j = 0; j < m; j++) {                 tree.get(i).add(0);             }         }     }      // Update function for bit list     public void update(int x, int y, int val) {         while (x <= n) {             int y1 = y;             while (y1 <= m) {                 bit.get(x).set(y1, bit.get(x).get(y1) + val);                 y1 += y1 & -y1;             }             x += x & -x;         }     }      // Query function for bit list     public int query(int x, int y) {         int s = 0;         while (x > 0) {             int y1 = y;             while (y1 > 0) {                 s += bit.get(x).get(y1);                 y1 -= y1 & -y1;             }             x -= x & -x;         }         return s;     }      // Compresses the bit list into a 2D tree     public void compress() {         for (int i = 1; i <= n; i++) {             for (int j = 1; j <= m; j++) {                 // Compute the sum of elements in the                 // corresponding rectangle                 tree.get(i - 1).set(j - 1, query(i, j)                                      - query(i - 1, j)                                      - query(i, j - 1)                                      + query(i - 1, j - 1));             }         }         bit.clear(); // Clear bit list after compression     }      // Getter function for compressed tree     public List<List<Integer>> getCompressedTree() {         return tree;     } }  // Main function public class Main {     public static void main(String[] args) {         // Initialize input matrix         List<List<Integer>> arr = new ArrayList<>(Arrays.asList(             Arrays.asList(1, 2, 3, 4, 5),             Arrays.asList(6, 7, 8, 9, 10),             Arrays.asList(11, 12, 13, 14, 15),             Arrays.asList(16, 17, 18, 19, 20)         ));          // Create Compressed2DBIT object and update with input         // matrix         Compressed2DBIT bit = new Compressed2DBIT(4, 5);         for (int i = 0; i < 4; i++) {             for (int j = 0; j < 5; j++) {                 bit.update(i + 1, j + 1, arr.get(i).get(j));             }         }       // Compress the bit list into a 2D tree bit.compress();           // Get the compressed tree and print it     List<List<Integer>> compressedTree = bit.getCompressedTree();     for (int i = 0; i < compressedTree.size(); i++) {         for (int j = 0; j < compressedTree.get(i).size(); j++) {             System.out.print(compressedTree.get(i).get(j) + " ");         }         System.out.println();     } } }         
Python3
# Define a class named Compressed2DBIT class Compressed2DBIT:    # Define the constructor   # with arguments n and m     def __init__(self, n, m):         self.n = n         self.m = m          # Create a 2D BIT (Binary Indexed         # Tree) with zeros, with dimensions         # n + 1 and m + 1 initialize 2D         # BIT with zeros         self.bit = [[0] * (m + 1) for _ in range(n + 1)]         self.tree = None      def update(self, x, y, val):         """         Update the value at (x, y) in the 2D array by adding `val` to it.         """          # Update the values in the BIT         # based on the provided x, y,         # and val         while x <= self.n:             y1 = y             while y1 <= self.m:                 self.bit[x][y1] += val                  # Compute the next y value                 # to update based on the                 # current y value                 y1 += y1 & -y1                  # Compute the next x value                 # to update based on the                 # current x value             x += x & -x      def query(self, x, y):         """         Query the sum of the elements in          the subarray from (1, 1) to (x, y)         """         s = 0         while x > 0:             y1 = y             while y1 > 0:                 s += self.bit[x][y1]                 y1 -= y1 & -y1             x -= x & -x         return s      def compress(self):         """         Compress the 2D array using the          Fenwick tree (Binary Indexed Tree)         technique.         """          # initialize compressed 2D array         # with zeros         self.tree = [             [0] * self.m for _ in range(self.n)]         for i in range(1, self.n + 1):             for j in range(1, self.m + 1):                  # Calculate the sum of the                 # elements in the subarray                 # from (1, 1) to (i, j)                 # using the formula:                 # sum(x1, y1, x2, y2) =                 # sum(x2, y2) - sum(x1-1, y2)                 # - sum(x2, y1-1) +                 # sum(x1-1, y1-1)                 self.tree[i-1][j-1] = self.query(i, j) - self.query(                     i-1, j) - self.query(i, j-1) + self.query(i-1, j-1)                  # set the 2D BIT to None                 # to save memory         self.bit_compressed = None   # Example usage arr = [[1, 2, 3, 4, 5],        [6, 7, 8, 9, 10],        [11, 12, 13, 14, 15],        [16, 17, 18, 19, 20]]  bit = Compressed2DBIT(4, 5) for i in range(4):     for j in range(5):         bit.update(i + 1, j + 1, arr[i][j])  print(bit.query(2, 3))  # expected output: 27 print(bit.query(4, 5))  # expected output: 210  bit.compress() print(bit.query(2, 3))  # expected output: 27 print(bit.query(4, 5))  # expected output: 210 # expected output: # [[1, 2, 3, 4, 5], [6, 7, 8, 9, 10], # [11, 12, 13, 14, 15], # [16, 17, 18, 19, 20]] print(bit.tree) 
C#
using System; using System.Collections.Generic;  class Program {   // Main  function   static void Main(string[] args)   {     // Initialize input matrix     List<List<int> > arr = new List<List<int> >() {       new List<int>() { 1, 2, 3, 4, 5 },       new List<int>() { 6, 7, 8, 9, 10 },       new List<int>() { 11, 12, 13, 14, 15 },       new List<int>() { 16, 17, 18, 19, 20 }     };      // Create Compressed2DBIT object and update with     // input matrix     Compressed2DBIT bit = new Compressed2DBIT(4, 5);     for (int i = 0; i < 4; i++) {       for (int j = 0; j < 5; j++) {         bit.update(i + 1, j + 1, arr[i][j]);       }     }      // Compress the bit list into a 2D tree     bit.compress();      // Get the compressed tree and print it     List<List<int> > compressedTree       = bit.getCompressedTree();     for (int i = 0; i < compressedTree.Count; i++) {       for (int j = 0; j < compressedTree[i].Count;            j++) {         Console.Write(compressedTree[i][j] + " ");       }       Console.WriteLine();     }   } }  // Compressed2DBIT class class Compressed2DBIT {   int n, m;   List<List<int> > bit, tree;    // Constructor   public Compressed2DBIT(int n, int m)   {     this.n = n;     this.m = m;      // Initialize bit and tree lists     bit = new List<List<int> >();     for (int i = 0; i <= n; i++) {       bit.Add(new List<int>());       for (int j = 0; j <= m; j++) {         bit[i].Add(0);       }     }      tree = new List<List<int> >();     for (int i = 0; i < n; i++) {       tree.Add(new List<int>());       for (int j = 0; j < m; j++) {         tree[i].Add(0);       }     }   }    // Update function for bit list   public void update(int x, int y, int val)   {     while (x <= n) {       int y1 = y;       while (y1 <= m) {         bit[x][y1] += val;         y1 += y1 & -y1;       }       x += x & -x;     }   }    // Query function for bit list   public int query(int x, int y)   {     int s = 0;     while (x > 0) {       int y1 = y;       while (y1 > 0) {         s += bit[x][y1];         y1 -= y1 & -y1;       }       x -= x & -x;     }     return s;   }    // Compresses the bit list into a 2D tree   public void compress()   {     for (int i = 1; i <= n; i++) {       for (int j = 1; j <= m; j++) {         // Compute the sum of elements in the         // corresponding rectangle         tree[i - 1][j - 1] = query(i, j)           - query(i - 1, j)           - query(i, j - 1)           + query(i - 1, j - 1);       }     }     bit.Clear(); // Clear bit list after compression   }    // Getter function for compressed tree   public List<List<int> > getCompressedTree()   {     return tree;   } }  // This code is contributed by Tapesh(tapeshdua420) 
JavaScript
class Compressed2DBIT {     constructor(n, m) {         this.n = n;         this.m = m;          // Initialize bit and tree arrays         this.bit = new Array(n + 1);         this.tree = new Array(n);          for (let i = 0; i <= n; i++) {             this.bit[i] = new Array(m + 1).fill(0);         }          for (let i = 0; i < n; i++) {             this.tree[i] = new Array(m).fill(0);         }     }      // Update function for bit array     update(x, y, val) {         while (x <= this.n) {             let y1 = y;             while (y1 <= this.m) {                 this.bit[x][y1] += val;                 y1 += y1 & -y1;             }             x += x & -x;         }     }      // Query function for bit array     query(x, y) {         let s = 0;         while (x > 0) {             let y1 = y;             while (y1 > 0) {                 s += this.bit[x][y1];                 y1 -= y1 & -y1;             }             x -= x & -x;         }         return s;     }      // Compresses the bit array into a 2D tree     compress() {         for (let i = 1; i <= this.n; i++) {             for (let j = 1; j <= this.m; j++) {                 // Compute the sum of elements in the corresponding rectangle                 this.tree[i - 1][j - 1] = this.query(i, j) - this.query(i - 1, j) - this.query(i, j - 1) + this.query(i - 1, j - 1);             }         }     }      // Getter function for compressed tree     getCompressedTree() {         return this.tree;     } }  // Initialize input matrix const arr = [     [1, 2, 3, 4, 5],     [6, 7, 8, 9, 10],     [11, 12, 13, 14, 15],     [16, 17, 18, 19, 20] ];  // Create Compressed2DBIT object and update with input matrix const bit = new Compressed2DBIT(4, 5); for (let i = 0; i < 4; i++) {     for (let j = 0; j < 5; j++) {         bit.update(i + 1, j + 1, arr[i][j]);     } }  // Test query function console.log(bit.query(2, 3)); // expected output: 27 console.log(bit.query(4, 5)); // expected output: 210  // Compress the bit array and test query function again bit.compress(); console.log(bit.query(2, 3)); // expected output: 27 console.log(bit.query(4, 5)); // expected output: 210  // Get compressed tree and print it const compressedTree = bit.getCompressedTree(); for (const row of compressedTree) {     console.log(row.join(" ")); } 

Output
27 210 27 210 [[1, 2, 3, 4, 5], [6, 7, 8, 9, 10], [11, 12, 13, 14, 15], [16, 17, 18, 19, 20]] 

Time Complexity: 

  • The time complexity of the update method is O(log*n * log*m) because it performs two nested while loops, each of which executes log*n (or log*m) times due to the bitwise operations inside the loop conditions.
  • The time complexity of the query method is also O(log n * log m) because it performs two nested while loops, each of which executes log n (or log m) times due to the bitwise operations inside the loop conditions.
  • The time complexity of the compress method is O(n * m * log*n * log*m) because it performs two nested for loops, each of which executes n (or m) times, and each iteration of the inner loop calls the query method four times, resulting in a time complexity of O(log n * log m) per iteration.

Auxiliary Space:

  • The space complexity of the Compressed2DBIT class is O(n * m) because it stores the original 2D array in a 2D binary indexed tree (self.bit) and stores the compressed 2D array in a separate 2D array (self.tree), both of which have dimensions n x m. 
  • Additionally, it stores the values of n and m, as well as a reference to the compressed 2D array (self.tree) and the compressed 2D binary indexed tree (self.bit_compressed). 
  • Therefore, the total space complexity is O(n * m) + O(1) = O(n * m).

Advantages of compressed 2D Binary Indexed tree:

  • Space efficiency: The compressed 2D BIT uses less memory than the standard 2D BIT. The standard 2D BIT stores a value for each cell in the 2D array, while the compressed 2D BIT stores a value for each row and column. This results in a significant reduction in memory usage for large arrays.
  • Faster construction time: The compressed 2D BIT can be constructed faster than the standard 2D BIT. The construction time of the compressed 2D BIT is O(n * m * log n * log m), where n and m are the dimensions of the array. This is faster than the construction time of the standard 2D BIT, which is O(n^2 * m^2 * log n * log m).
  • Faster range queries: The compressed 2D BIT can perform range queries faster than the standard 2D BIT. Range queries are typically faster because the compressed 2D BIT requires fewer memory accesses and fewer operations to calculate the query result.
  • Simplicity: The compressed 2D BIT is simpler to implement and use than the standard 2D BIT. The compressed 2D BIT requires only one-dimensional BIT operations, which are simpler and easier to understand than the two-dimensional operations required by the standard 2D BIT.

Disadvantages of compressed 2D Binary Indexed tree:

  • Limited functionality: The compressed 2D BIT can only support range sum queries and point updates. It cannot support other types of queries such as range minimum queries or range maximum queries.
  • Slower point updates: Point updates on the compressed 2D BIT are slower than on the standard 2D BIT. This is because updating a single cell in the compressed 2D BIT requires recalculating the sums for all cells in the row and column containing the cell being updated.
  • Loss of information: The compressed 2D BIT stores only the row and column sums of the 2D array, and not the individual cell values. This means that information about the individual cells is lost, which may be important in some applications.
  • More complex implementation: While the compressed 2D BIT is simpler to understand than the standard 2D BIT, its implementation can be more complex. The compressed 2D BIT requires additional bookkeeping to keep track of the row and column sums, and the compression process can be tricky to get right.

Next Article
Implementation of B-Tree in C

I

ianurag
Improve
Article Tags :
  • Tree
  • DSA
  • Binary Indexed Tree
Practice Tags :
  • Tree

Similar Reads

  • Implementation of B-Tree in C
    The B-tree is a self-balancing ordered structured data that stores data in a set of pages and also allows efficient searching, insertion, and deletion operations. It has its origin in a generic form of binary search trees developed by Rudolf Bayer and Edward M. McCreight in 1972. It is capable of pr
    5 min read
  • Implementation of B+ Tree in C
    A B+ tree is a self-balancing tree data structure that maintains sorted data and allows searching, inserting, and deletion of data in logarithmic time. In B+ trees, the actual data is stored inside the leaf nodes and the internal nodes act as pointers to the leaf nodes. In this article, we will lear
    15+ min read
  • B-Tree Implementation in C++
    In C++, B-trees are balanced tree data structures that maintain sorted data and allow searches, sequential access, insertions, and deletions in logarithmic time. B-trees are generalizations of binary search trees (BST) in that a node can have more than two children. B-trees are optimized for systems
    13 min read
  • B*-Trees implementation in C++
    B*-tree of order m is a search tree that is either empty or that satisfies three properties: The root node has minimum two and maximum 2 floor ((2m-2)/3) +1 children Other internal nodes have the minimum floor ((2m-1)/3) and maximum m children All external nodes are on the same level. The advantage
    10 min read
  • Compress a Binary Tree into an integer diagonally
    Given a Binary Tree consisting of N nodes, the task is to first compress the tree diagonally to get a list of integers and then, again compress the list to get a single integer using the following operations: When a tree is compressed diagonally, its value in binary representation gets compressed.Co
    10 min read
  • Implementing a Binary Tree in Java
    A binary tree is a hierarchical data structure composed of the nodes. Each node contains the value and references to its left child node and right child node, which are also binary trees that are possibly null. The structure resembles the tree with the nodes branching out from a central root, where
    5 min read
  • Binary Tree (Array implementation)
    Given an array that represents a tree in such a way that array indexes are values in tree nodes and array values give the parent node of that particular index (or node). The value of the root node index would always be -1 as there is no parent for root. Construct the standard linked representation o
    6 min read
  • Linked complete binary tree & its creation
    A complete binary tree is a binary tree where each level 'l' except the last has 2^l nodes and the nodes at the last level are all left-aligned. Complete binary trees are mainly used in heap-based data structures. The nodes in the complete binary tree are inserted from left to right in one level at
    15 min read
  • Binary Tree Representation
    Binary tree is a tree data structure (non-linear) in which each node can have at most two children which are referred to as the left child and the right child. The topmost node in a binary tree is called the root, and the bottom-most nodes are called leaves. A binary tree can be visualized as a hier
    4 min read
  • Print Binary Tree in 2-Dimensions
    Given a Binary Tree, the task is to print the tree in a 2-dimensional layout. Examples: Input: Output: 1 2 3 4 5 Input: Output: 1 2 Table of Content Using Inorder Traversal - O(n) Time and O(n) SpaceUsing Preorder Traversal - O(n) Time and O(n) SpaceUsing Level Order Traversal - O(n) Time and O(n) S
    15+ min read
geeksforgeeks-footer-logo
Corporate & Communications Address:
A-143, 7th Floor, Sovereign Corporate Tower, Sector- 136, Noida, Uttar Pradesh (201305)
Registered Address:
K 061, Tower K, Gulshan Vivante Apartment, Sector 137, Noida, Gautam Buddh Nagar, Uttar Pradesh, 201305
GFG App on Play Store GFG App on App Store
Advertise with us
  • Company
  • About Us
  • Legal
  • Privacy Policy
  • In Media
  • Contact Us
  • Advertise with us
  • GFG Corporate Solution
  • Placement Training Program
  • Languages
  • Python
  • Java
  • C++
  • PHP
  • GoLang
  • SQL
  • R Language
  • Android Tutorial
  • Tutorials Archive
  • DSA
  • Data Structures
  • Algorithms
  • DSA for Beginners
  • Basic DSA Problems
  • DSA Roadmap
  • Top 100 DSA Interview Problems
  • DSA Roadmap by Sandeep Jain
  • All Cheat Sheets
  • Data Science & ML
  • Data Science With Python
  • Data Science For Beginner
  • Machine Learning
  • ML Maths
  • Data Visualisation
  • Pandas
  • NumPy
  • NLP
  • Deep Learning
  • Web Technologies
  • HTML
  • CSS
  • JavaScript
  • TypeScript
  • ReactJS
  • NextJS
  • Bootstrap
  • Web Design
  • Python Tutorial
  • Python Programming Examples
  • Python Projects
  • Python Tkinter
  • Python Web Scraping
  • OpenCV Tutorial
  • Python Interview Question
  • Django
  • Computer Science
  • Operating Systems
  • Computer Network
  • Database Management System
  • Software Engineering
  • Digital Logic Design
  • Engineering Maths
  • Software Development
  • Software Testing
  • DevOps
  • Git
  • Linux
  • AWS
  • Docker
  • Kubernetes
  • Azure
  • GCP
  • DevOps Roadmap
  • System Design
  • High Level Design
  • Low Level Design
  • UML Diagrams
  • Interview Guide
  • Design Patterns
  • OOAD
  • System Design Bootcamp
  • Interview Questions
  • Inteview Preparation
  • Competitive Programming
  • Top DS or Algo for CP
  • Company-Wise Recruitment Process
  • Company-Wise Preparation
  • Aptitude Preparation
  • Puzzles
  • School Subjects
  • Mathematics
  • Physics
  • Chemistry
  • Biology
  • Social Science
  • English Grammar
  • Commerce
  • World GK
  • GeeksforGeeks Videos
  • DSA
  • Python
  • Java
  • C++
  • Web Development
  • Data Science
  • CS Subjects
@GeeksforGeeks, Sanchhaya Education Private Limited, All rights reserved
We use cookies to ensure you have the best browsing experience on our website. By using our site, you acknowledge that you have read and understood our Cookie Policy & Privacy Policy
Lightbox
Improvement
Suggest Changes
Help us improve. Share your suggestions to enhance the article. Contribute your expertise and make a difference in the GeeksforGeeks portal.
geeksforgeeks-suggest-icon
Create Improvement
Enhance the article with your expertise. Contribute to the GeeksforGeeks community and help create better learning resources for all.
geeksforgeeks-improvement-icon
Suggest Changes
min 4 words, max Words Limit:1000

Thank You!

Your suggestions are valuable to us.

What kind of Experience do you want to share?

Interview Experiences
Admission Experiences
Career Journeys
Work Experiences
Campus Experiences
Competitive Exam Experiences