If we were "old school" about this:
-
Given that you said "grid" that implies a simple two dimensional array.
-
In order to know if each cell has an open passage to its neighbour in some direction only requires 1 bit. (0 closed, 1 open) So only four bits need to be saved in each cell to represent passages, north, south, east, west. Or you might need 8 bits if diagonal passages are allowed.
-
So, each cell need only hold a u8, the bits of which are used to hold the open/closed passage of each direction out of the cell.
-
Of course you are likely to want to store some other data in each cell, so better make each element of that array a struct with that "neighbours" byte in it and whatever other fields you need.
That is how I did a maze generation algorithm on a TRS-80 computer back in 1980 something. Worked a treat in the 4 kilo bytes of memory available on that machine.
Moving forward, I recently wanted to generate the mazes of the "Hunt The Wumpus" game in Rust: Hunt the Wumpus - Wikipedia
To that end I put all the caves of the game into elements of a vector of structures and created passages between them simply storing the índices of open passages in those elements.
As discussed here: When is a linked list not a linked list?. With code.