C語言之環形佇列

嵌入式Linux知識共享發表於2023-05-14

一、環形佇列的優勢

環形佇列是一種特殊的佇列,它可以解決普通佇列在使用時空間利用不充分的問題。在環形佇列中,當佇列滿時,佇列的尾指標指向佇列的起始位置,而不是指向佇列的最後一個元素。這樣可以在不浪費空間的情況下儲存更多的元素。
下面我們來詳細講解一下環形佇列的實現。

二、環形佇列的定義

首先,我們需要定義一個環形佇列的結構體,包含以下成員變數:

  • int *queue:指向環形佇列的指標;
  • int front:指向佇列的頭部;
  • int rear:指向佇列的尾部;
  • int size:佇列的容量。
typedef struct {
    int *queue;
    int front;
    int rear;
    int size;
} MyCircularQueue;

三、環形佇列的初始化

在初始化環形佇列時,我們需要為其動態分配記憶體空間,並將頭指標和尾指標都初始化為-1,表示佇列為空。

MyCircularQueue* myCircularQueueCreate(int k) 
{
    MyCircularQueue *obj =(MyCircularQueue*)malloc(sizeof(MyCircularQueue));
obj
->queue = (int *)malloc(sizeof(int) * k); obj->front = -1; obj->rear = -1; obj->size = k; return obj; }

四、環形佇列的入隊

當向佇列中插入元素時,我們需要先判斷佇列是否已滿。如果佇列已滿,則插入失敗,返回false;否則,將元素插入到佇列的尾部,並將尾指標指向下一個位置。

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

    obj->rear = (obj->rear + 1) % obj->size;
    obj->queue[obj->rear] = value;
    if (obj->front == -1) 
  { obj
->front = obj->rear; } return true; }

五、環形佇列的出隊

當從佇列中刪除元素時,我們需要先判斷佇列是否為空。如果佇列為空,則刪除失敗,返回false;否則,將元素從佇列的頭部刪除,並將頭指標指向下一個位置。

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

    if (obj->front == obj->rear) 
    {
        obj->front = -1;
        obj->rear = -1;
        return true;
    }

    obj->front = (obj->front + 1) % obj->size;

    return true;
}

 六、環形佇列的檢視隊首元素

當檢視佇列的頭部元素時,我們需要先判斷佇列是否為空。如果佇列為空,則返回-1;否則返回佇列頭部的元素。

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

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

 七、環形佇列的檢視隊尾元素

當檢視佇列的尾部元素時,我們需要先判斷佇列是否為空。如果佇列為空,則返回-1;否則,返回佇列尾部的元素。

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

    return obj->queue[obj->rear];
}    

八、環形佇列的判斷是否為空

當判斷佇列是否為空時,只需要判斷頭指標是否為-1即可。

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

 九、環形佇列的判斷是否已滿

當判斷佇列是否已滿時,只需要判斷尾指標下一個位置是否為頭指標即可。

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

十、環形佇列的銷燬

當環形佇列不再使用時,需要釋放其佔用的記憶體空間。

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

總的來說,環形佇列是一種非常實用的資料結構,特別適用於空間有限的情況下。透過合理的設計和實現,可以使得佇列的空間利用率更高,並且操作效率也比較高。


 

關於更多嵌入式C語言、FreeRTOS、RT-Thread、Linux應用程式設計、linux驅動等相關知識,關注公眾號【嵌入式Linux知識共享】,後續精彩內容及時收看了解。

相關文章