The reason behind this behaviour is that when we pull the list of topics, we don't know ahead of time which are deleted and which aren't. In addition, admins are able to see the content of these topics, whereas regular users are not. Lastly, users can have different "topics per page" settings.
Therefore this content isn't cacheable, and so if we wanted to hide deleted topics, we'd have to do the following:
- User A has topics per page set to 10, retrieve top 10 topics in category B
- Expand those 10 and discover 7 of them were deleted. (3 remain)
At this point we can either serve page 1 as a three-topic page (that's bad), or continue:
- poll for page 2, retrieve another 10
- Expand those 10 and discover 4 were deleted (9 remain).
- Repeat from #3 until we have 10 topics
Now, imagine if you have pages and pages of deleted topics. NodeBB would be churning and making multiple calls to the db just to retrieve page 1. That's an anti-pattern 
Secondly, let's go from page 1 to page 2... how do we determine what topics are on page 2? We can't simply retrieve items 10-20 anymore, since 10-20 were actually part of page 1 now, once we factored in the deleted topics.
This kind of headache-inducing logic is why we have to show "This post is deleted!" or "This topics is deleted!".
Let's say we did cache it... then we'd have to store the cache per user (or per user postsperpage-group-hash, possibly), and then we'd have to deal with cache invalidation, plus the inevitable bug reports since this entire system is hugely fragile from the get-go.
... and that's at a high level, imagine how many more edge cases we'd have to account for, and much more complex it would be once we actually started coding it!