Which of the following methods is a more correct way to initialize a variable?
// int x = NULL;  `NULL` implies pointer
int x = 0;        // 0 implies integer value and x is an integer.
What about the pointers?
void *p = NULL;  // `NULL` implies pointer and p is a pointer.
//void *p = 0;   // 0 implies integer value
that NULL is equal to 0 
It is equal in value, though maybe not in bit pattern.  See below +0.0, -0.0 example.
If NULL was equal to 0, always, then there would not be a need for it in C.
NULL is a null pointer consonant - it often, but does not always have a bit pattern of zeros.  A pointer with a NULL value will always compare equally to 0: same value, different bit patterns.
Remember that == compares values, not bit patterns.
void *a = NULL;
if (a == NULL) Always_True();
if (a == 0) Always_True();
Example that may help.  +0.0 and -0.0 have the same value, same type, but different bit patterns.  Similar thing may happen with pointers.
int main(void) {
  double pz = +0.0;
  double nz = -0.0;
  printf("=:%d  bits:%d\n", pz == nz, memcmp(&pz, &nz, sizeof pz) == 0);  // =:1  bits:0
  return 0;
}