【C】循环队列(力扣622)

循环队列

    • 与普通队列的比较
    • 基本要素
      • 数组
      • 头下标(front)
      • 尾下标(rear)
      • 容量(capacity)
    • 注意事项

与普通队列的比较

首先,我们在实现普通队列时基本用的都是链表实现的(也可以用顺序表,但是不好用),但是我们的循环队列用的是顺序表,也就是数组形式的,只不过定义的时候要多定义几个要素。都有什么呢?

基本要素

数组

用来存放元素

头下标(front)

用来标记当前队列中的首元素

尾下标(rear)

用来标记当前队列中的尾元素

容量(capacity)

用来保存当前队列的最大存储个数

typedef int QDataType; 

typedef struct 
{
    QDataType* q;
    int front;
    int rear;
    int N;
} MyCircularQueue;

注意事项

首先,循环队列之所以叫循环队列,就是因为它其中的被删除的某一元素的空间可以被重复利用,而我们想要重复利用这块空间的话,就要用到front和rear这两个指针(其实也不是指针,就是下标)。循环队列玩的就是这两个下标。

增删查改四个功能,查和改就不说了,增删的注意事项我们挨个来说。

但是在说这四个功能之前得要先规定一些东西。

循环队列,队头为front,队尾为rear,循环队列长度为N,最多存储N-1个数据。

初始化:先开辟数组(数组大小是你自己指定的,不能随便更改),然后将front和rear都置零,将capacity给好(你指定的大小)。

MyCircularQueue* myCircularQueueCreate(int k) 
{
    MyCircularQueue* queue = (MyCircularQueue*)malloc(sizeof(MyCircularQueue));
    queue->q = (QDataType*)malloc(sizeof(QDataType) * (k + 1));
    queue->front = queue->rear = 0;
    queue->N = k + 1;

    return queue;
}

判空的条件:front == rear
【C】循环队列(力扣622)_第1张图片

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

判满的条件:(rear + 1) % N == front ,这个自己算下理顺了就行,没必要死记
【C】循环队列(力扣622)_第2张图片

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

出队

注意事项:

  1. 出队要先判断队列是否为空。
  2. 每次我们删除元素的时候需要将front往后挪一个单位,也就是front++,但是当front位于逻辑结构中的末尾时,再++一次,就需要将front挪回0的位置。
    看图:
    【C】循环队列(力扣622)_第3张图片
bool myCircularQueueDeQueue(MyCircularQueue* obj) 
{
    if(myCircularQueueIsEmpty(obj))
    {
        return false;
    }
    else
    {
        obj->front = (obj->front + 1 + obj->N) % obj->N;
        return true;
    }
}

入队

入队的注意事项:

  1. 判断当前队列是否满了
  2. 如果没满,添加元素的时候rear往后挪,但是当rear位于逻辑结构的末尾时就需要将其挪到最前面,这时候就不是简单的++了,是rear = (rear + 1) % N,一样,这个自己理顺了就行,不需要死记。
    【C】循环队列(力扣622)_第4张图片
bool myCircularQueueEnQueue(MyCircularQueue* obj, int value) 
{
    if(myCircularQueueIsFull(obj))
    {
        return false;
    }
    else
    {
        obj->q[obj->rear] = value;
        obj->rear = (obj->rear + 1) % obj->N;
        return true;
    }
}

获得队头元素

int myCircularQueueFront(MyCircularQueue* obj) 
{
    if(myCircularQueueIsEmpty(obj))
    {
        return -1;//如果是空返回-1
    }
    else
    {
        return obj->q[obj->front];
    }
}

获得队尾元素

int myCircularQueueRear(MyCircularQueue* obj) 
{
    if(myCircularQueueIsEmpty(obj))
    {
        return -1;//如果是空返回-1
    }
    else
    {
        return obj->q[(obj->rear - 1 + obj->N) % obj->N];
    }
}

结束。

你可能感兴趣的:(基本数据结构,c语言,leetcode,数据结构)