Practical OJ question - Designing a circular queue

Preface: Today we will implement a circular queue.

Insert image description here

Insert image description here

Implementation of each interface

Create queue:

typedef struct {
    
    
    int* a;
    int front;
    int back;
    int k;
    
} MyCircularQueue;

Our queue is stored in an array, so we have to define an array in our queue. Front represents our first element, back points to the next element in our array, and k is the length.

Initialize the queue:

MyCircularQueue* myCircularQueueCreate(int k) {
    
    
    MyCircularQueue* obj=(MyCircularQueue*)malloc(sizeof(MyCircularQueue));
    obj->a=(int*)malloc(sizeof(int)*(k+1));
    obj->front=0;
    obj->back=0;
    obj->k=k;
    return obj;
}

Determine if the queue is empty:

bool myCircularQueueIsEmpty(MyCircularQueue* obj) {
    
    
    return obj->front==obj->back;
    
}

Front represents the subscript of the head element of our array, and back points to the next subscript of the tail element of our array. If our front=back, then it is empty.

Determine whether the queue is full:

bool myCircularQueueIsFull(MyCircularQueue* obj) {
    
    
    return (obj->back+1)%(obj->k+1)==obj->front;
    }

If back+1==front, it will be full. If our circular queue loops a few more times, then our subscript size will be greater than the length of our array, so we need to modulo our length. If our back+ If ==front of k+1 in module 1 is full, then it is full.

Insert data into the queue:

bool myCircularQueueEnQueue(MyCircularQueue* obj, int value) {
    
    
    if(myCircularQueueIsFull(obj))
    return false;

    obj->a[obj->back]=value;
   obj-> back++;
    obj->back%=(obj->k+1);
    return true;    
}

Our back points to the next element at the end of our queue, so after we assign a value to the queue, our back may be greater than the length of the array, so our back needs to be modulo the length of the array.

Queue deletion data:

bool myCircularQueueDeQueue(MyCircularQueue* obj) {
    
    
    if(myCircularQueueIsEmpty(obj))
    return false;

    ++obj->front;
    obj->front%=(obj->k+1);
    return true;    
}

We can delete the first element of the queue as long as front++ accesses the next one. Our current front is the subscript of the first element. Our front may also be greater than the array length, and we also need to modulo the array length.

Return the first element of the queue:

int myCircularQueueFront(MyCircularQueue* obj) {
    
    
    if(myCircularQueueIsEmpty(obj))
    return -1;

    return obj->a[obj->front];
    
}

Get the last element of the queue:

int myCircularQueueRear(MyCircularQueue* obj) {
    
    
    if(myCircularQueueIsEmpty(obj))
    return -1;

    return obj->a[(obj->back-1+obj->k+1)%(obj->k+1)];
    
}

Our back points to the next element of the tail element of the queue. The subscript of our tail element is back-1. If our back is 0, it will cause an error, so we add an array length, and our The subscript of the last element of the queue may also be greater than the array length, so we also need to modulate the array length.

Complete code display:

typedef struct {
    
    
    int* a;
    int front;
    int back;
    int k;
    
} MyCircularQueue;


MyCircularQueue* myCircularQueueCreate(int k) {
    
    
    MyCircularQueue* obj=(MyCircularQueue*)malloc(sizeof(MyCircularQueue));
    obj->a=(int*)malloc(sizeof(int)*(k+1));
    obj->front=0;
    obj->back=0;
    obj->k=k;
    return obj;
}
    

bool myCircularQueueIsEmpty(MyCircularQueue* obj) {
    
    
    return obj->front==obj->back;
    
}

bool myCircularQueueIsFull(MyCircularQueue* obj) {
    
    
    return (obj->back+1)%(obj->k+1)==obj->front;
    }

bool myCircularQueueEnQueue(MyCircularQueue* obj, int value) {
    
    
    if(myCircularQueueIsFull(obj))
    return false;

    obj->a[obj->back]=value;
   obj-> back++;
    obj->back%=(obj->k+1);
    return true;
    
}

bool myCircularQueueDeQueue(MyCircularQueue* obj) {
    
    
    if(myCircularQueueIsEmpty(obj))
    return false;

    ++obj->front;
    obj->front%=(obj->k+1);
    return true;

    
}

int myCircularQueueFront(MyCircularQueue* obj) {
    
    
    if(myCircularQueueIsEmpty(obj))
    return -1;

    return obj->a[obj->front];
    
}

int myCircularQueueRear(MyCircularQueue* obj) {
    
    
    if(myCircularQueueIsEmpty(obj))
    return -1;

    return obj->a[(obj->back-1+obj->k+1)%(obj->k+1)];
    
}



void myCircularQueueFree(MyCircularQueue* obj) {
    
    
    free(obj->a);
    free(obj);
}

If it helps everyone, please support it!

Guess you like

Origin blog.csdn.net/Lehjy/article/details/134842813