はじめに:この記事の最後に完全な実装コードがあります。最初に段階的な実装を実装します。つまり、これを行う理由と循環キューを段階的に実装する方法について説明します。
コンテンツ
3.チームの運営については、いくつかのルールを理解してください
まず、キューの概念
食堂で食べ物を買うために列に並んでいると理解できます。列の最後(列に入る)でしか列に並ぶことができず、列の先頭にいる学生は食事の購入を終えて出発します(列から外れます)。したがって、チームの理解は非常に明確です。チームは、チームの先頭でのデキュー操作とチームの最後でのエントリ操作のみを許可するチームです。つまり、チームは先入れ先出しのテーブルです。(FIFO)
チームの基本的な操作
(1)チームの初期化
(2)、チームが空かどうかを判断します
(3)、キューの長さを見つけます
(4)キュー操作
(5)、デキュー操作
(6)、チームの最初の要素を探す
3.チームの運営については、いくつかのルールを理解してください
(1)、最初にフロントとリアを使用して、現在のキューヘッドの前の位置とテール要素をマークします。
(2)判断が空である、つまり、前面と背面の両方が同じ位置としてマークされている。
(3)、この段落を理解してください:次に、キューがいっぱいであるとどのように判断しますか?キューをキューに入れ続けた場合、後部マークの位置はMaxsize-1であると言えます(配列の添え字があるため)は0からです最初に、Maxsize-1は最後の位置を表します)、キューがいっぱいになったとき?もちろん、チームリーダーがデキュー操作を実行できるため、これは当てはまりません。フラグビットがリアフラグビットになるまでキューがデキューされると、キューはいっぱいになりませんが、チームは空になります。したがって、この状況を変える方法を考え出す必要があります。これにより、循環キューが作成されます。このチームを循環キューとして設定できるため、常に循環してキューに出入りできます。では、チームが満員であるとどのように判断するのでしょうか。式((rear + 1)%Maxsize == front)が確立されている場合、チームは満員です。これは、フロントがキューの先頭をマークする前の要素であり、リアがテール要素を指しているためである理由を分析できます。(rear + 1)%Masizeは、リアが最後の位置(Maxsize-1)を指さないようにすることを意味します。追加する場合1の場合、配列の最大添え字を超えたMaxsizeであり、Maxsizeの余りを取ると、rear + 1がMaxsizeになり、Maxsizeの余りを取ると、0になります。最初の位置でキューに戻るので、そうする必要があります。(rear + 1)%Maxsize == frontは、リアが正しい範囲を超えないようにします。リアの次のフロントがフロントの場合、フロントを指す位置を空けたため、チームは満員になります。つまり、フロントはそれを指します。チームのヘッド要素の前の位置、この位置は何も格納しません。(rear + 1)%Maxsizeまたは(front + 1)%Maxsizeおよびそれらの%Maxsize操作はすべて、rearまたはfront + 1がMaisizeの位置を指している場合に、それを0に変換します。
第四に、キューの基本的な操作を実装します
最初にキュー構造を宣言します
#include <stdio.h>
#include <stdlib.h>
#define Maxsize 5
//顺序队列的实现
//重新定义数据类型,typedef在这里的意思就是重新定义它后面的东西的别名
typedef int ElemType;//这句话的意思就是定义int的别名为ElemType来代替int
//声明一个结构体
typedef struct Queue
{
ElemType data[Maxsize];//队列能存多少元素
int front,rear; //front指向队列的前一个元素,rear指向队列的最后一个元素,即队尾
}SqQueue; //重新定义结构体的名字为SqQueue
(1)チームの初期化
//先进行初始化操作
void Init(SqQueue *s)
{
s->front=s->rear=0; //将队首和队尾标记队列相同的位置
}
(2)、チームが空かどうかを判断します
//判断队列是否为空
int Empty(SqQueue s)
{
if(s.front==s.rear) //因为我们在初始化的时候将它们两个相等了,所以判空直接判断
return 1; //为空返回真
else
return 0; //不为空返回假,程序中除了0全为真
}
(3)、キューの長さを見つけます
キューの長さを求めるには、まずキューが空かどうかを判断します。空でない場合は、後部が前部よりも大きいかどうかを判断します。後部が前部よりも大きい場合は、直接減算できます。後部が前部よりも小さい場合、減算は負の数に加えてMaxsizeです。つまり、減算が正の数の場合、Maxsizeを加算し、残りのMaxsizeを取得できます。この場合、後部かどうかは関係ありません。フロントを開発するかどうかにかかわらず、(s.rear-s.front + Maxsize)%Maxsizeを使用して表すことができます
//求队列的长度
int Length(SqQueue s)
{
//先判断队列是否为空
if(Empty(s)) //意思是如果队列为空则返回1,那么if括号里面的意思是不等于0的话执行里面的东西
{
return 0;
}
return (s.rear-s.front+Maxsize)%Maxsize;
}
(4)キュー操作
//入队操作
void Add(SqQueue *s,ElemType x)//将x入队
{
//首先判断队列是否已满
if(s->front==(s->rear+1)%Maxsize) //队列中留出一个空位置让front指向它,那么当rear+1等于front的话我们就说队满了
{
printf("当前队列已满,不能将值为:%d的元素入队\n\n",x);
return;
}
else
{
s->data[(s->rear+1)%Maxsize]=x;//在rear的下一个位置存入元素x
s->rear=(s->rear+1)%Maxsize; //把rear的位置往后移一位
}
}
(5)、デキュー操作
//出队操作
void Dele(SqQueue *s,ElemType *e) //用e来保存出队的元素
{
if(Empty(*s))
{
printf("当前队列为空,操作失败\n\n");
return;
}
else
{
*e=s->data[(s->front+1)%Maxsize];//用e来保存出队的这个元素
s->front=(s->front+1)%Maxsize; //出队之后front往后移动一位
}
}
(6)、チームの最初の要素を探す
//读取队首元素
ElemType Get(SqQueue s)
{
if(Empty(s)) //意思是如果队列为空则返回1,那么if括号里面的意思是不等于0的话执行里面的东西
{
printf("队首元素不存在,队列为空\n\n");
return 0;
}
return s.data[(s.front+1)%Maxsize];//返回队首元素,这样做的目的是防止front当前的位置在Maxsize这个位置
}
(7)、主な機能
int main()
{
SqQueue s;//定义一个队,名称s;这里也可以定义一个队指针,用这个指针来代替这个表s,修改一下函数中的参数就行。只是实现方式不同,结果相同
//进行初始化
Init(&s);
ElemType e=0;
int x;
printf("先将队列初始化之后的头标记为:%d 尾标记为:%d\n\n",s.front,s.rear);
printf("队列的大小为:%d\n\n",Maxsize);
//来五次入队操作
Add(&s,8);
Add(&s,5);
Add(&s,4);
Add(&s,0);
Add(&s,7);
//看一下当前队的长度
x=Length(s);
if(x)
{
printf("操作完成之后,当前队列的长度为:%d\n\n",Length(s));
}
//读取队首元素
x=Get(s);
if(x) //如果x不为0,执行里面的东西
{
printf("当前队列中的队首元素为:%d\n\n",x);
}
//出队操作
Dele(&s,&e);
Dele(&s,&e);
Dele(&s,&e);
//读取队首元素
x=Get(s);
if(!(x==0&&e==0)) //如果x和e不为0,执行里面的东西
{
printf("出队操作之后,刚刚出队的元素为:%d,当前队首元素为:%d\n\n",e,x);
}
return 0;
}
(8)、実行結果
(9)、完全なコード
#include <stdio.h>
#include <stdlib.h>
#define Maxsize 5
//顺序队列的实现
//重新定义数据类型,typedef在这里的意思就是重新定义它后面的东西的别名
typedef int ElemType;//这句话的意思就是定义int的别名为ElemType来代替int
//声明一个结构体
typedef struct Queue
{
ElemType data[Maxsize];//队列能存多少元素
int front,rear; //front指向队列的前一个元素,rear指向队列的最后一个元素,即队尾
}SqQueue; //重新定义结构体的名字为SqQueue
//先进行初始化操作
void Init(SqQueue *s)
{
s->front=s->rear=0; //将队首和队尾标记队列相同的位置
}
//判断队列是否为空
int Empty(SqQueue s)
{
if(s.front==s.rear) //因为我们在初始化的时候将它们两个相等了,所以判空直接判断
return 1; //为空返回真
else
return 0; //不为空返回假,程序中除了0全为真
}
//求队列的长度
int Length(SqQueue s)
{
//先判断队列是否为空
if(Empty(s)) //意思是如果队列为空则返回1,那么if括号里面的意思是不等于0的话执行里面的东西
{
return 0;
}
return (s.rear-s.front+Maxsize)%Maxsize;
}
//读取队首元素
ElemType Get(SqQueue s)
{
if(Empty(s)) //意思是如果队列为空则返回1,那么if括号里面的意思是不等于0的话执行里面的东西
{
printf("队首元素不存在,队列为空\n\n");
return 0;
}
return s.data[(s.front+1)%Maxsize];//返回队首元素,这样做的目的是防止front当前的位置在Maxsize这个位置
}
//入队操作
void Add(SqQueue *s,ElemType x)//将x入队
{
//首先判断队列是否已满
if(s->front==(s->rear+1)%Maxsize) //对列中留出一个空位置让front指向它,那么当rear+1等于front的话我们就说队满了
{
printf("当前队列已满,不能将值为:%d的元素入队\n\n",x);
return;
}
else
{
s->data[(s->rear+1)%Maxsize]=x;//在rear的下一个位置存入元素x
s->rear=(s->rear+1)%Maxsize; //把rear的位置往后移一位
}
}
//出队操作
void Dele(SqQueue *s,ElemType *e) //用e来保存出队的元素
{
if(Empty(*s))
{
printf("当前队列为空,操作失败\n\n");
return;
}
else
{
*e=s->data[(s->front+1)%Maxsize];
s->front=(s->front+1)%Maxsize;
}
}
int main()
{
SqQueue s;//定义一个队,名称s;这里也可以定义一个队指针,用这个指针来代替这个表s,修改一下函数中的参数就行。只是实现方式不同,结果相同
//进行初始化
Init(&s);
ElemType e=0;
int x;
printf("先将队列初始化之后的头标记为:%d 尾标记为:%d\n\n",s.front,s.rear);
printf("队列的大小为:%d\n\n",Maxsize);
//来五次入队操作
Add(&s,8);
Add(&s,5);
Add(&s,4);
Add(&s,0);
Add(&s,7);
//看一下当前队的长度
x=Length(s);
if(x)
{
printf("操作完成之后,当前队列的长度为:%d\n\n",Length(s));
}
//读取队首元素
x=Get(s);
if(x) //如果x不为0,执行里面的东西
{
printf("当前队列中的队首元素为:%d\n\n",x);
}
//出队操作
Dele(&s,&e);
Dele(&s,&e);
Dele(&s,&e);
x=Get(s);
if(!(x==0&&e==0))
{
printf("出队操作之后,刚刚出队的元素为:%d,当前队首元素为:%d\n\n",e,x);
}
return 0;
}
要約する
循環キューの難しさは、キューが空か満杯かを判断する方法であり、後部が最後の位置を指すとキューに入り、前部が最後の位置を指すとデキュー操作を実行します、キューが必要です。Maxsizeはモジュロ演算を実行します。シーケンステーブル、リンクリスト、スタック、およびチームの演算は非常に似ています。それらを比較できます。いずれかの演算をマスターしている限り、他の演算を簡単に解決できます。そしてあなたの心の中に論理を内面化します。私の能力は限られています。声明に何か問題がある場合は、私を批判して訂正してください。