データ構造のキュー(循環キュー)の基本的な操作と実装

はじめに:この記事の最後に完全な実装コードがあります。最初に段階的な実装を実装します。つまり、これを行う理由と循環キューを段階的に実装する方法について説明します。

コンテンツ

まず、キューの概念

チームの基本的な操作

3.チームの運営については、いくつかのルールを理解してください

第四に、キューの基本的な操作を実装します

(1)チームの初期化

(2)、チームが空かどうかを判断します

(3)、キューの長さを見つけます

(4)キュー操作

(5)、デキュー操作

(6)、チームの最初の要素を探す

(7)、主な機能

(8)、実行結果

 (9)、完全なコード

要約する


まず、キューの概念

       食堂で食べ物を買うために列に並んでいると理解できます。列の最後(列に入る)でしか列に並ぶことができず、列の先頭にいる学生は食事の購入を終えて出発します(列から外れます)。したがって、チームの理解は非常に明確です。チームは、チームの先頭でのデキュー操作とチームの最後でのエントリ操作のみを許可するチームです。つまり、チームは先入れ先出しのテーブルです。(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はモジュロ演算を実行します。シーケンステーブル、リンクリスト、スタック、およびチームの演算は非常に似ています。それらを比較できます。いずれかの演算をマスターしている限り、他の演算を簡単に解決できます。そしてあなたの心の中に論理を内面化します。私の能力は限られています。声明に何か問題がある場合は、私を批判して訂正してください。

おすすめ

転載: blog.csdn.net/BaoITcore/article/details/121300975