Guys, I mentioned the phrase 'made up pseudocode' in the OP because I was asking for a language agnostic design pattern.
Sorry, missed the pseudocode bit!
If your topology isn't arbitrary - e.g. your rooms lie in a 2D grid, and connections are only N/S/E/W, then you have more options. For example storing the rooms in a 2D array and having per-room flags to say which directions are exits. Then getting the next room is defined by the direction and the grid. But I'm guessing this isn't the case from the OP?
If your topology *is* arbitrary, interconnected rooms with arbitrary topology form a graph. The rooms are the nodes, and the connections are edges. There's lots of computer science research about representing graphs, might be worth looking at.
For something I was working on recently, where I was modifying things on the fly, I stored the nodes and edges in two arrays, and the nodes didn't know about the edges. It meant a fair bit of trawling the edge array to find relevant connections, but it wasn't really the performance problem I was expecting it to be. I think for most uses this is overkill though, and the solution where the room contains the connections as per your pseudocode is easier.
Certainly something I will keep in mind, though I would definitely include a check against all existing IDs (even if the chances are quite slim, I can't simply trust the RNG to never pick the same number twice.)
If you want to generate unique IDs, I think you'd be much better off doing:
new_id = generator
generator = generator + 1
then you know you'll never get a collision until the generator wraps around, and you don't need to mess around detecting collisions. If you have a large generator (32-bit and up) you can pretty much ignore the wrap around. It doesn't matter that they're random or not, isn't the uniqueness the point?
[edit: Radnom just said the same thing in fewer words!]
Will