はじめに: 今日は循環キューを実装します。
各インターフェースの実装
キューを作成します。
typedef struct {
int* a;
int front;
int back;
int k;
} MyCircularQueue;
キューは配列に格納されているため、キューに配列を定義する必要があります。Front は最初の要素を表し、back は配列内の次の要素を指します。k は長さです。
キューを初期化します。
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;
}
Front は配列の先頭要素の添字を表し、back は配列の末尾要素の次の添字を指します。front=back の場合、空です。
キューがいっぱいかどうかを判断します。
bool myCircularQueueIsFull(MyCircularQueue* obj) {
return (obj->back+1)%(obj->k+1)==obj->front;
}
back+1==front の場合、満杯になります。循環キューがさらに数回ループすると、添え字のサイズが配列の長さより大きくなるため、長さを剰余する必要があります。 =モジュール 1 の k+1 の前がいっぱいで、その後はいっぱいになります。
データをキューに挿入します。
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;
}
back はキューの末尾にある次の要素を指しているため、キューに値を割り当てた後、back は配列の長さを超える可能性があるため、back は配列の長さを剰余する必要があります。
キュー削除データ:
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)];
}
back は、キューの末尾要素の次の要素を指します。末尾要素の添え字は back-1 です。back が 0 の場合、エラーが発生するため、配列の長さを追加します。キューの最後の要素も配列の長さを超える可能性があるため、配列の長さを調整する必要もあります。
完全なコードの表示:
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);
}
皆さんのお役に立てましたら、ぜひサポートをお願いします!