LeetCode622。循環キューを設計する

タイトル説明

622.循環キューを設計する-LeetCode(LeetCode)

循環キューの実装を設計します。循環キューは線形データ構造であり、その動作はFIFO(先入れ先出し)の原則に基づいており、行の終わりは行の先頭の後に接続されてループを形成します。「リングバッファ」とも呼ばれます。

循環キューの利点の1つは、このキューの以前に使用されたスペースを使用できることです。通常のキューでは、キューがいっぱいになると、キューの前にまだスペースがある場合でも、次の要素を挿入できません。ただし、循環キューを使用すると、これらのスペースを使用して新しい値を格納できます。

実装は次の操作をサポートする必要があります。

•MyCircularQueue(k):コンストラクター。キューの長さをkに設定します。
•フロント:チームのトップから要素を取得します。キューが空の場合は、-1を返します。
•リア:テールエレメントを取得します。キューが空の場合は、-1を返します。
•enQueue(value):要素を循環キューに挿入します。正常に挿入されるとtrueを返します。
•deQueue():循環キューから要素を削除します。正常に削除されるとtrueを返します。
•isEmpty():循環キューが空かどうかを確認します。
•isFull():循環キューがいっぱいかどうかを確認します。

例1:

MyCircularQueue circularQueue = new MyCircularQueue(3); // 设置长度为 3
circularQueue.enQueue(1); // 返回 true
circularQueue.enQueue(2); // 返回 true
circularQueue.enQueue(3); // 返回 true
circularQueue.enQueue(4); // 返回 false,队列已满
circularQueue.Rear(); // 返回 3
circularQueue.isFull(); // 返回 true
circularQueue.deQueue(); // 返回 true
circularQueue.enQueue(4); // 返回 true
circularQueue.Rear(); // 返回 4

思考分析

この問題は配列を使用して実装されます。2つのポインタが与えられると、1つはキューの先頭(フロント)を指し、もう1つはキューの末尾(リア)を指します。Rear+ 1 = Frontの場合、循環キューはいっぱいです。また、Rear = Frontの場合、循環キューは空です。
ここに画像の説明を挿入
•配列、ヘッドポインター、テールポインター、キュー内のカウント数を含む構造を作成します

typedef struct {
    
    
    int* a;
    //头
    int Front;
    //尾
    int Rear;
    int k;

} MyCircularQueue;

•キューを初期化し、k + 1 intサイズのスペースを開き、ヘッドポインタとテールポインタを0に等しくします。

MyCircularQueue* myCircularQueueCreate(int k) {
    
    
    MyCircularQueue* p = (MyCircularQueue*)malloc(sizeof(MyCircularQueue));
    p->a = (int*)malloc((k + 1) * sizeof(int));
    p->Front = p->Rear = 0;
    p->k = k;
    return p;
}

•データを入力するには、最初にキューがいっぱいかどうか、いっぱいの場合は直接false、いっぱいでない場合は値を直接テールポインターに置き、テールポインターの場合はテールポインターを+1にします。 k + 1の位置を指し、Rear = 0に設定します

bool myCircularQueueEnQueue(MyCircularQueue* obj, int value) {
    
    
    if(myCircularQueueIsFull(obj))
        return false;
    obj->a[obj->Rear] = value;
    ++obj->Rear;
    if(obj->Rear == obj->k + 1)
    {
    
    
        obj->Rear = 0;
    }
    return true;
}

•データを削除するには、最初にキューが空かどうか、空の場合は直接false、空でない場合は+ヘッドポインタ、ヘッドポインタの位置がk + 1の場合は、Frontを0とします。

bool myCircularQueueDeQueue(MyCircularQueue* obj) {
    
    
    if(myCircularQueueIsEmpty(obj))
    {
    
    
        return false;
    }
    ++obj->Front;
    if(obj->Front == obj->k + 1)
    obj->Front = 0;
    return true;
}

•ヘッドノードに戻り、最初にキューが空かどうかを判断します。キューが空の場合は直接-1を返し、空でない場合はヘッドポインタが指すノードに直接戻ります。

int myCircularQueueFront(MyCircularQueue* obj) {
    
    
    if(myCircularQueueIsEmpty(obj))
    {
    
    
        return -1;
    }
    else
    {
    
    
        return obj->a[obj->Front];
    }
}

•テールノードに戻り、最初にキューが空かどうかを判断します。キューが空の場合は直接-1を返し、空でない場合はリア-1のノードに戻ります。
特殊なケース:Rear = 0の場合、Rearを許可します。-1 = k

int myCircularQueueRear(MyCircularQueue* obj) {
    
    
    if(myCircularQueueIsEmpty(obj))
        return -1;
    int prev = obj->Rear - 1;
    if(obj->Rear == 0)
    {
    
    
        prev = obj->k;
    }
    return obj->a[prev];
}

•キューが空かどうかを判断します。ヘッドポインタとテールポインタが等しい場合、キューは空です。キューが空の場合はtrueを返します。空でない場合はfalseを返します。

bool myCircularQueueIsEmpty(MyCircularQueue* obj) {
    
    
    if(obj->Front == obj->Rear)
    {
    
    
        return true;
    }
    else
    {
    
    
        return false;
    }
}

•循環キューがいっぱいで空であるため、キューがいっぱいかどうかを判断します。キューがいっぱいになると、キューの先頭と末尾の間に距離があります。すべて、Rear + 1 = Frontの場合、防止するためにいっぱいになります。配列の添え字を超えているため、Rear +1がk + 1の位置に移動するときは、Rear + 1を0に設定して、サイクルが満たされるようにします。

bool myCircularQueueIsFull(MyCircularQueue* obj) {
    
    
    int next = obj->Rear + 1;
    //让下标循环,如果next超过数组,则置为0
    //防止判满next超过数组下标
    if(next == obj->k + 1)
    {
    
    
        next = 0;
    }
    //判满如果Rear+1==Front则满了true,否则没满false
    if(next == obj->Front)
    {
    
    
        return true;
    }
    else
    {
    
    
        return false;
    }
}

コード

typedef struct {
    
    
    int* a;
    //头
    int Front;
    //尾
    int Rear;
    int k;

} MyCircularQueue;
bool myCircularQueueIsEmpty(MyCircularQueue* obj);
bool myCircularQueueIsFull(MyCircularQueue* obj);

MyCircularQueue* myCircularQueueCreate(int k) {
    
    
    MyCircularQueue* p = (MyCircularQueue*)malloc(sizeof(MyCircularQueue));
    p->a = (int*)malloc((k + 1) * sizeof(int));
    p->Front = p->Rear = 0;
    p->k = k;
    return p;
}

bool myCircularQueueEnQueue(MyCircularQueue* obj, int value) {
    
    
    if(myCircularQueueIsFull(obj))
        return false;
    obj->a[obj->Rear] = value;
    ++obj->Rear;
    if(obj->Rear == obj->k + 1)
    {
    
    
        obj->Rear = 0;
    }
    return true;
}

bool myCircularQueueDeQueue(MyCircularQueue* obj) {
    
    
    if(myCircularQueueIsEmpty(obj))
    {
    
    
        return false;
    }
    ++obj->Front;
    if(obj->Front == obj->k + 1)
    obj->Front = 0;
    return true;
}

int myCircularQueueFront(MyCircularQueue* obj) {
    
    
    if(myCircularQueueIsEmpty(obj))
    {
    
    
        return -1;
    }
    else
    {
    
    
        return obj->a[obj->Front];
    }
}

int myCircularQueueRear(MyCircularQueue* obj) {
    
    
    if(myCircularQueueIsEmpty(obj))
        return -1;
    int prev = obj->Rear - 1;
    if(obj->Rear == 0)
    {
    
    
        prev = obj->k;
    }
    return obj->a[prev];
}

bool myCircularQueueIsEmpty(MyCircularQueue* obj) {
    
    
    if(obj->Front == obj->Rear)
    {
    
    
        return true;
    }
    else
    {
    
    
        return false;
    }
}

bool myCircularQueueIsFull(MyCircularQueue* obj) {
    
    
    int next = obj->Rear + 1;
    //让下标循环,如果next超过数组,则置为0
    //防止判满next超过数组下标
    if(next == obj->k + 1)
    {
    
    
        next = 0;
    }
    //判满如果Rear+1==Front则满了true,否则没满false
    if(next == obj->Front)
    {
    
    
        return true;
    }
    else
    {
    
    
        return false;
    }
}

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

/**
 * Your MyCircularQueue struct will be instantiated and called as such:
 * MyCircularQueue* obj = myCircularQueueCreate(k);
 * bool param_1 = myCircularQueueEnQueue(obj, value);
 
 * bool param_2 = myCircularQueueDeQueue(obj);
 
 * int param_3 = myCircularQueueFront(obj);
 
 * int param_4 = myCircularQueueRear(obj);
 
 * bool param_5 = myCircularQueueIsEmpty(obj);
 
 * bool param_6 = myCircularQueueIsFull(obj);
 
 * myCircularQueueFree(obj);
*/

おすすめ

転載: blog.csdn.net/weixin_50886514/article/details/114751541