Better implementation to find the root of an element in QuickUnion implementation of UnionFind problem
The time complexity for both versions is exactly the same. It is linear in terms of the distance between $p$ and the $root$.

Space complexity is a little different.
It's easy to see that the iterative version will use constant space.
The recursive function will use linear space on paper (each recursive call must store some information about the current function call, for instance in a call stack via stack pointer).

This might give problems, if the distance between $p$ and $root$ is very long. Image a tree with $id[0] = 0$ and $id[p] = p - 1$ for $p &gt; 0$. Then finding the root for a large element $p$ might exceed the allocated stack and crash the program.

However in practice the situation might look a bit different. Depending on the programming language, the compiler/interpreter, configuration this linear space can be optimized to constant space. The concept that allows such an optimization is called tail recursion. E.g. gcc -O3 will generate exactly the same assembler code for both versions: example. But be careful, not all languages, compiler / interpreter have these optimizations implemented.