Read from right to left: double * * is a pointer to a pointer to a double. Some people try to shorten "pointer to pointer" as "double pointer" but that creates confusion with "pointer to double".
You have to remember that a pointer is still just a variable, it is passed by value to a function. This means that when tree is NULL and you call new on it, you are changing the value of the local "tree". This is not to be confused with changing the value of the dereferenced pointer.
Which is exactly why your solution works. You pass a pointer to the pointer, and in that way you can dereference it and change the value of the original tree.
You could also pass the pointer by reference, which will make things a little simpler: