The issue here is that when you write &x[20], you are getting back the address of the 20th element of the array x. Once you've created the array x, you can't change where its elements appear in memory. You can change the contents of the array elements, but where those elements are isn't going to change. As a result, writing &x[20] = ins is illegal, since the most natural interpretation of this statement is "move the 20th element of x to the spot pointed at by ins."
On the other hand, the code x[20] = ins is better (but it still has an issue). That means "change the contents of the 20th element of the array x to hold the address stored in ins." Keep in mind that there's a difference between "the address stored in x[20]" (which is given by x[20]) and "the address of x[20]," which is given by (&x[20]).
The problem with that line of code is that x[20] has type node and ins has type node*. Did you mean to make x a node** (a pointer to an array of node*s? If you make that change, that line should compile.
Technically speaking, the issue here is that the address-of operator returns an rvalue, but you can only put lvalues on the left-hand side of an assignment statement. An rvalue is a value like 137 or "hello" that represents, in some sense, a "pure value" that isn't the name of some place you can put something. Writing something like 137 = x isn't legal because you can't store x "in" 137, the same way that writing &x[20] = ins isn't legal because you can't store ins "in" &x[20].