Is the following the correct implementation of the Q learning algorithm for a neural network?
Your pseudocode is fairly close to something that could be implemented. There are a couple of omissions, where it is not clear whether your implementation would do the right thing. There are a few non-general assumptions that are worth noting - they don't prevent you implementing for a specific purpose, but do prevent you writing the most generic DQN that you could. There is one mistake that prevents it working at all.

Your mistake is here:


  Do gradient step where error = (y - max(q1))^2, only the max of q1 gets any gradient


The loss function and gradient must be applied to the state/action pair s1, a1, i.e. the action that was taken. This is an important distinction for when the agent takes exploratory (non-greedy) actions, as it must if it is going to learn about their values.

A corrected statement might read: Do gradient step where error = (y - Q(s1,a1))^2, only the output for a1 gets any gradient.



Regarding the rest of the pseudocode I could make the following observations:


  The state, s1, is initialised randomly


This is fine if it is possible. However, it is more usual in Q learning to initialise the state to whatever the normal start of the episode would be. That might be from some randomised starting rules, but that is not quite the same as 
picking a random state from all possible states.


  action a1 is chosen based off the max of q1 (or randomly)


It is not quite clear what you mean by "or randomly". For Q learning - and most RL - exploration is important. So this is not a design time choice for your algorithm, but a runtime choice that must itself be made so that all actions can be tried. Typically you would use an $\epsilon$-greedy policy here that took the argmax action by default, but with probability $\epsilon$ took a random sample from actions with same chance of each possible action.


  state s2 is found by progressing s1 based on a1


This is one of a few places where you have not quite captured the nature of a time step in a general MDP. You appear to have made the assumption that rewards are directly associated with states (with language like "reward at s2"). Whilst some MDPs are like that, it is not true in general.

A better, more general statement might be:

s2, reward, done are found by taking a step from s1, using a1 as the action

Typically the environment (or a wrapper for it that establishes state representations and rewards) will provide a step method that returns the tuple $s_{t+1}, r_{t+1}, (s_{t+1} = s_T)$, although you could also hold these values in the environment model for the current time step and return them as required.

This statement:


  (The "otherwise" doesn't match bellmans equation as α=1)


I don't know which Bellman equation you are referring to, but they don't include a learning rate, $\alpha$ in any version I have seen. Perhaps you are referring to a tabular Q learning update? In any case, it doesn't seem relevant, as whatever learning rate you are using is now inside the gradient step, and does not need to be part of the pseuodcode.

Finally, regarding this:


  I am also not taking into account storing network states (in this case, the network is called Q) for proper learning to avoid catastrophic forgetting, as I'm more concerned on getting the specifics right before good practice.


DQN will very likely not work at all, for most environments, unless you implement experience replay i.e. training the neural network on a random sample of stored s1,a1,r,s2,done taken from a table that you build up on each time step. Usually you cannot simply use the latest data from the current step. This is not just "good practice", but an almost-always necessary stability improvement.