前回の記事に引き続き、スタックに関する知識内容を学びました。次に、スタックに似たもう一つの特殊な線形テーブルであるキューについて学びましょう。この記事の目的は、スタックの概念を理解して理解することです。キューを作成し、循環キューを実現します
目次
5. キューをクリアし、キューの先頭の要素を返し、キュー内の要素の数を返します。
1. 待ち行列を知る
1. キューの概念
キュー: 一方の端でデータを挿入し、もう一方の端でデータを削除することのみを許可する特殊な線形テーブルです。キューには先入れ先出しの特性があります。キューの最後にデータを挿入することをキューに入ると言います。キューの先頭のデータを削除することをデキューと呼びます。
写真が示すように:
2. キューの実装
キューは、順次リストとリンク リストの 2 つの方法で実装でき、キューは循環キューと非循環キューに分けられます。
区別する:
1. 非循環キューの場合、配列の構造を使用すると、キューを配列の先頭に出力すると効率が低下するため、リンク リストの構造を使用することをお勧めします。
2. 循環キューを使用する場合、配列を使用する方が便利で簡潔です。唯一の欠点は、循環キューに配列を使用する場合、静的配列のみであることです。動的な循環キューは形成できません。もちろん、循環リンク リストを使用することもできます。
第二に、循環キューを実現する
配列の構造を使用して循環キューを実装します。
1. 構造体のフォーマットと初期化
コードは以下のように表示されます:
#define MAXSIZE 11//表示的是数组的元素个数,多一个1,是为了留给rear空间的
typedef struct SqQueue {
int data[MAXSIZE];
int front;//队头
int rear;//队尾 front 和 rear 就是指针(类似)
}SqQueue;
//初始化队列
void InitQueue(SqQueue* ps) {
//初始化队列只需要队头队尾都为0 表示下标起始位置
ps->front = ps->rear = 0;
}
実際には静的配列を使用しており、この方法でのみ循環キューを実現できます。動的配列の場合、循環効果は達成できず、定義された MAXSIZE サイズは 11 であり、値を保存しません。記号として。
2. キューの最後に要素を (キューに) 挿入します。
最も重要なポイントは理解することです
(rear+1)%MAXSIZE==front キューがフルかどうかを判定するフラグです
写真が示すように:
コードは以下のように表示されます:
//队尾插入元素
void EnQueue(SqQueue* ps,int data) {
//插入的时候先进行判满
if ((ps->rear + 1) % MAXSIZE == ps->front) {//最多存储MAXSIZE-1个元素
//表示已经满了
perror("队列已经满了,无法加入新元素\n");
exit(-1);//stdlib.h 头文件里面的
}
ps->data[ps->rear] = data;
ps->rear = (ps->rear + 1) % MAXSIZE;
}
3. キューの先頭のデータを削除(キュー外)
写真が示すように:
コードは以下のように表示されます:
//队头出队
//只需要移动指针位置即可
void OutQueue(SqQueue* ps, int* data) {
//出队先判别是否为空
if (ps->rear == ps->front) {
perror("为空队列,无法出队\n");
exit(-1);
}
*data = ps->data[ps->front];
ps->front = (ps->front + 1) % MAXSIZE;
//不需要整体移动只要将队头指针后移就可以
}
4. 印刷する
写真が示すように:
コードは以下のように表示されます:
//遍历打印元素
void PrintQueue(SqQueue* ps) {
int i = 0;
printf("Queue->");
while ((i + ps->front)%MAXSIZE != ps->rear) {
//从front的队头位置开始,i从0开始 ++一直到等于rear结束
printf("%d->", ps->data[i + ps->front]);
i = (i + 1) % MAXSIZE;
}
printf("NULL\n");
}
5. キューをクリアし、キューの先頭の要素を返し、キュー内の要素の数を返します。
コードは以下のように表示されます:
//将队列清空
void ClearQueue(SqQueue* ps) {
ps->front = ps->rear = 0;
}
//返回队头元素
void GetHead(SqQueue* ps, int* data) {
if (ps->front == ps->rear) {
perror("为空队列\n");
exit(-1);
}
*data = ps->data[ps->front];
}
//返回队列中的元素个数
int CountSqQueue(SqQueue* ps) {
return (ps->rear - ps->front + MAXSIZE) % MAXSIZE;
}
3. 完全なコード実装
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<malloc.h>
#include<assert.h>
#include<stdlib.h>
//构建的是循环队列,是使用数组的形式,完成的循环队列
#define MAXSIZE 11//表示的是数组的元素个数,多一个1,是为了留给rear空间的
typedef struct SqQueue {
int data[MAXSIZE];
int front;//队头
int rear;//队尾 front 和 rear 就是指针(类似)
}SqQueue;
//初始化队列
void InitQueue(SqQueue* ps) {
//初始化队列只需要队头队尾都为0 表示下标起始位置
ps->front = ps->rear = 0;
}
//将队列清空
void ClearQueue(SqQueue* ps) {
ps->front = ps->rear = 0;
}
//队尾插入元素
void EnQueue(SqQueue* ps,int data) {
//插入的时候先进行判满
if ((ps->rear + 1) % MAXSIZE == ps->front) {//最多存储MAXSIZE-1个元素
//表示已经满了
perror("队列已经满了,无法加入新元素\n");
exit(-1);//stdlib.h 头文件里面的
}
ps->data[ps->rear] = data;
ps->rear = (ps->rear + 1) % MAXSIZE;
}
//队头出队
//只需要移动指针位置即可
void OutQueue(SqQueue* ps, int* data) {
//出队先判别是否为空
if (ps->rear == ps->front) {
perror("为空队列,无法出队\n");
exit(-1);
}
*data = ps->data[ps->front];
ps->front = (ps->front + 1) % MAXSIZE;
//不需要整体移动只要将队头指针后移就可以
}
//遍历打印元素
void PrintQueue(SqQueue* ps) {
int i = 0;
printf("Queue->");
while ((i + ps->front)%MAXSIZE != ps->rear) {
//从front的队头位置开始,i从0开始 ++一直到等于rear结束
printf("%d->", ps->data[i + ps->front]);
i = (i + 1) % MAXSIZE;
}
printf("NULL\n");
}
//返回队头元素
void GetHead(SqQueue* ps, int* data) {
if (ps->front == ps->rear) {
perror("为空队列\n");
exit(-1);
}
*data = ps->data[ps->front];
}
//返回队列中的元素个数
int CountSqQueue(SqQueue* ps) {
return (ps->rear - ps->front + MAXSIZE) % MAXSIZE;
}
int main() {
SqQueue Q;
InitQueue(&Q);
EnQueue(&Q, 1);
EnQueue(&Q, 2);
EnQueue(&Q, 3);
EnQueue(&Q, 4);
EnQueue(&Q, 5);
PrintQueue(&Q);
int a = 0;
OutQueue(&Q, &a);
PrintQueue(&Q);
EnQueue(&Q, 1);
EnQueue(&Q, 2);
//EnQueue(&Q, 3);
EnQueue(&Q, 4);
EnQueue(&Q, 4);
EnQueue(&Q, 5);
EnQueue(&Q, 5);
PrintQueue(&Q);
}
要約する
この記事では、キューの新しい概念について説明します。また、配列の構造を通じて循環キューを実装します。循環キューを実装するこの方法は、比較的単純で理解しやすいです。主なことは、たとえば、MAXSIZE に余分なスペースが必要な理由を理解することです。 11 に設定します。空の判定、完全な判定、操作があります。これが最も重要です。
空判定:リア==フロント
ジャッジメントフル:(リア+1)%MAXSIZE==フロント
キュー要素の数を取得します: (rear-front+MAXSIZE)%MAXSIZE
フロント、リア、i の次の位置を取得する方法:
例: リア=(リア+1)%MAXSIZE