> Moreover, I somewhat find the way in which the depth (height) relates to the number of nodes at each level confusing to me. Perhaps because I think of how the Heap is represented both as an array and as a tree. But I know that with every deeper i, the Heap splits children such that its got 2^i nodes at each i.
Okay. It seems to me that you get it. At the end of this post I will show an exact calculation of the heap's height.
> The while loop runs in O(log n) time because the worst case depth an element could have is the whole height of the tree.
Also there's implicit in your argument the fact that the body of the while loop takes O(1) time. It's perfectly reasonable that you omitted this obvious fact in writing down your explanation. This and the rest of your argument are correct.
Now here's how I would calculate the exact height of the complete binary tree. Let's first note that the first k levels of the tree can hold 1, 2, 4, 8, ..., 2^(k-1) nodes, respectively. Then the first k levels of the tree can hold a total of 1 + 2 + 4 + 8 + ... + 2^(k-1) nodes. That sum equals 2^k - 1. So, if we have a complete tree with n nodes, where 2^k <= n < 2^(k+1), the first k levels of the tree cannot hold all the nodes, and the first k + 1 nodes suffices. A complete tree will thus have k+1 levels when log_2 (2^k) <= log_2(n) < log_2(2^(k+1)), that is, when k <= log_2(n) < k + 1. Note that log_2 is the log base 2 function. If we take a value x such that k <= x < k + 1, where k is an integer, then k = floor(x). So k + 1 = floor(x) + 1, or in this case, floor(log_2(n)) + 1.
So the number of levels of a complete tree with n elements is floor(log_2(n)) + 1.
Usually, instead of computing the inequalities all carefully, I prefer to just take some examples and notice the pattern.
n #levels
1 1
2 2
3 2
4 3
5 3
6 3
7 3
8 4
9 4
...
15 4
16 5
...
It's pretty clear it increases by 1 every time you hit a power of two, and you'll want to invert the 2^x function, and playing around with guesses like log_2(n) and floor(log_2(n)) and ceil(log_2(n)), you can fix up the right formula that way. Of course "noticing a pattern" is not a proof, just a good way to find the answer, or to check the answer you've found by other means.