My Queue implementation is correct? I have read CLRS Introduction to Algorithms book, now I'm on Elementary data structure chapter. I read about queue concept and try to implement in c.
I have tested a lot it work fine, but I have a little doubt on its working. Please tell me this implementation is correct or not. 

#include &lt;stdio.h&gt;
#include &lt;stdlib.h&gt;
#define MAX 4
struct queue {
    int array[MAX];
    int head;
    int tail;   
};
void ENQUEUE(struct queue* p,int data) {
// error checking for overflow
    if((p-&gt;tail == MAX-1 &amp;&amp; p-&gt;head == 0 ) || (p-&gt;head == p-&gt;tail+1)) {
        printf("\nQUEUE IS FULL!!   ");
        return;
    }
    p-&gt;array[p-&gt;tail] = data; 
    if(p-&gt;tail == MAX-1)
        p-&gt;tail = 0;
    else
        p-&gt;tail = p-&gt;tail+1;
    printf("\n%d data is added",data);
}

int DEQUEUE(struct queue* p) {
    if(p-&gt;head == p-&gt;tail) {
        printf("\nQUEUE IS EMPTY!!");
        return -1;
    }
    int x = p-&gt;array[p-&gt;head];
    if(p-&gt;head == MAX-1)
        p-&gt;head = 0;
    else
        p-&gt;head = p-&gt;head+1;
    printf("\n%d data is removed",x);
    return x;
}
void SHOWQUEUE(struct queue* p) {
    int i = 0;
    i = p-&gt;head;
    printf("p-&gt;head = %d &amp; p-&gt;tail = %d",p-&gt;head,p-&gt;tail);
    printf("\nQUEUE ELEMENTS:");

    while(i != p-&gt;tail) {
        printf("%d ",p-&gt;array[i]);
        if(i == (MAX-1)) 
            i = 0;

        else
            i = i+1;
    }
}
int main() {
    struct queue* Q;
    Q = (struct queue*) malloc(sizeof (struct queue));
    if(Q == NULL) {
        printf("Memory allocation failed");
        return -1;
    }
    Q-&gt;head = 1;
    Q-&gt;tail = 1; 
/*  ENQUEUE(Q,1);
    SHOWQUEUE(Q);
    DEQUEUE(Q);
    SHOWQUEUE(Q);
    ENQUEUE(Q,1);
    ENQUEUE(Q,1);
    SHOWQUEUE(Q);

    ENQUEUE(Q,1);
    ENQUEUE(Q,1);
    ENQUEUE(Q,1);
    SHOWQUEUE(Q);
    printf("head = %d &amp; tail = %d ",Q-&gt;head,Q-&gt;tail);
*/
    ENQUEUE(Q,98);
    ENQUEUE(Q,20);
    ENQUEUE(Q,16);
    ENQUEUE(Q,2);
//  ENQUEUE(Q,1);
//  ENQUEUE(Q,2);
    SHOWQUEUE(Q);
    DEQUEUE(Q);
    DEQUEUE(Q);
    SHOWQUEUE(Q);
    ENQUEUE(Q,5);
    SHOWQUEUE(Q);
    ENQUEUE(Q,3);
    SHOWQUEUE(Q);
    ENQUEUE(Q,10);
    SHOWQUEUE(Q);   
    DEQUEUE(Q);
    SHOWQUEUE(Q);
    ENQUEUE(Q,12);
    DEQUEUE(Q);
    SHOWQUEUE(Q);
    ENQUEUE(Q,2);
    DEQUEUE(Q);

    SHOWQUEUE(Q);
    ENQUEUE(Q,1);
    SHOWQUEUE(Q);
    DEQUEUE(Q);
    SHOWQUEUE(Q);
    DEQUEUE(Q);
    SHOWQUEUE(Q);
    DEQUEUE(Q);
    SHOWQUEUE(Q);
    DEQUEUE(Q);
    SHOWQUEUE(Q);
    return 0;
}
1 It would be more natural to have a field size instead of tail:

struct queue {
    int array[MAX];
    int head;
    int tail;   
};


2 If you had size field, checking whether the queue is empty or 
full would be a simple one-liner.

    if((p-&gt;tail == MAX-1 &amp;&amp; p-&gt;head == 0 ) || (p-&gt;head == p-&gt;tail+1)) {
        printf("\nQUEUE IS FULL!!   ");
        return;
    }


3 It's not cool to print from algorithms unless debugging.

int DEQUEUE(struct queue* p) {
    if(p-&gt;head == p-&gt;tail) {
        printf("\nQUEUE IS EMPTY!!");
        return -1;
    }


4 Can make the output of this more pretty.

void SHOWQUEUE(struct queue* p) {
    ...
}


5 The convention is not to prepend malloc with a type.

Q = (struct queue*) malloc(sizeof (struct queue));


Instead, do this

Q = malloc(sizeof(struct queue));


6 Don't do this:

Q-&gt;head = 1;
Q-&gt;tail = 1; 


Instead, you should write the function that initializes your queue.

7 Above, it's funny that you start indexing from 1.

Summa summarum

You could consider something like the following:

queue.h:

#ifndef QUEUE_H
#define QUEUE_H

#include &lt;stdbool.h&gt;
#include &lt;stdlib.h&gt;

#define CAPACITY 10

typedef struct queue {
    int storage[CAPACITY];
    size_t head;
    size_t size;
} queue;

void queue_init(queue* q);
bool queue_enqueue(queue* q, int element);
int  queue_dequeue(queue* q);
void queue_print(queue* q);

#endif


queue.c

#include "queue.h"
#include &lt;stdlib.h&gt;
#include &lt;stdbool.h&gt;
#include &lt;stdio.h&gt;

void queue_init(queue* q)
{
    if (!q) 
    {
        return;
    }

    q-&gt;head = 0;
    q-&gt;size = 0;
}

bool queue_enqueue(queue* q, int element)
{
    if (!q || q-&gt;size == CAPACITY)
    {
        return false;
    }

    q-&gt;storage[(q-&gt;head + q-&gt;size++) % CAPACITY] = element;
    return true;
}

int queue_dequeue(queue* q)
{
    if (!q || q-&gt;size == 0)
    {
        return 0;
    }

    int ret = q-&gt;storage[q-&gt;head];
    q-&gt;head = (q-&gt;head + 1) % CAPACITY;
    q-&gt;size--;
    return ret;
}

void queue_print(queue* q)
{
    if (!q)
    {
        printf("null");
        return;
    }

    printf("[");

    for (size_t i = 0, index = q-&gt;head; i &lt; q-&gt;size; ++i)
    {
        printf("%d", q-&gt;storage[index]);

        if (i &lt; q-&gt;size - 1)
        {
            printf(", ");
        }

        index = (index + 1) % CAPACITY;
    }

    printf("]");
}


main.c:

#include "queue.h"
#include &lt;stdio.h&gt;

int main() {
    queue q;
    queue_init(&amp;q);

    for (int i = 0; i &lt; 5; ++i)
    {
        queue_enqueue(&amp;q, i);
    }

    for (int i = 0; i &lt; 10; ++i)
    {
        queue_print(&amp;q);
        puts("");
        queue_enqueue(&amp;q, queue_dequeue(&amp;q));
    }

    return 0;
}


Hope that helps.