for (int p=1; p < a.size(); p++) {
int tmp = a[p];
for(j=p; j>0 && tmp < a[j-1]; j--) {
a[j] = a[j-1];
}
a[j] = tmp;
}
>
The outer loop executes n times.
Each run of the inner loop executes somewhere between 0 and p-1 times, where p varies from 0 to n. In the worse case, it will execute p-1 times. If p varies from 0 to n, then on average, p is n/2. So, the worst-case complexity for the inner loop is O(p-1) = O(n/2-1) = O(n).
Apart from the loops, the code is all O(1) (mostly importantly, the code inside the inner loop is), so it's only the loops that matter.
O(n) * O(n) = O(n^2).
QED.
This is roughly the analysis you yourself gave.