Basic operations and implementation of queues of data structures (circular queues)

Introduction: There is a complete implementation code at the end of this article. We will implement step-by-step implementation first, that is, we will discuss why we do this and how we should implement the circular queue step by step.

content

First, the concept of queue

The basic operation of the team

3. For the operation of the team, understand a number of rules

Fourth, implement the basic operations of the queue

(1) Initialization of the team

(2), determine whether the team is empty

(3), find the length of the queue

(4) Queue operation

(5), dequeue operation

(6), seek the first element of the team

(7), the main function

(8), running results

 (9), complete code

Summarize


First, the concept of queue

       We can understand the queue as queuing to buy food in the cafeteria. We can only queue at the end of the queue (entering the queue), and then the students at the head of the queue finish buying the meal and leave (dequeue operation). Therefore, the understanding of the team is very clear. The team is a team that only allows the dequeue operation at the head of the team and the entry operation at the end of the team. That is, the team is a first-in, first-out table. (FIFO)

The basic operation of the team

(1) Initialization of the team

(2), determine whether the team is empty

(3), find the length of the queue

(4) Queue operation

(5), dequeue operation

(6), seek the first element of the team

3. For the operation of the team, understand a number of rules

(1), we first use front and rear to mark the previous position and tail elements of the current queue head.

(2) Judgment is empty, that is, both front and rear are marked as the same position.

(3), understand this paragraph: then how do we judge that the queue is full, if we let the queue continue to enter the queue, then can we say that the position of the rear mark is Maxsize-1 (because the array subscript is from 0 At the beginning, Maxsize-1 represents the last position), when the queue is full? Of course, this is not the case, because our team leader can perform the dequeue operation. When the team continues to be dequeued until the flag bit is the rear flag bit, the queue is not full, but the team is empty. So we have to figure out a way to change this situation. This leads to a circular queue. We can set this team as a circular queue, so that we can always enter and exit the queue in a circle. So how do we judge the team is full? The formula ((rear+1)%Maxsize==front), if established, the team is full. We can analyze why this is because front is the previous element that marks the head of the queue, rear points to the tail element, (rear+1)%Masize means to prevent rear from pointing to the last position (Maxsize-1), when it adds When it is 1, it is Maxsize, which has exceeded the maximum subscript of the array, and if we take the remainder of Maxsize, when rear+1 becomes Maxsize and then take the remainder of Maxsize, it becomes 0, and it returns to the queue the first position, so it is necessary for us to do so. (rear+1)%Maxsize==front prevents the rear from going beyond the right range. When the next front of the rear is the front, the team is full, because we have vacated a position to point the front to it, that is, the front points to it The previous position of the head element of the team, this position does not store anything. (rear+1)%Maxsize or (front+1)%Maxsize and their %Maxsize operations are all to convert it to 0 when rear or front+1 points to the Maisize position.

Fourth, implement the basic operations of the queue

First declare a queue structure

#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) Initialization of the team

//先进行初始化操作
void Init(SqQueue *s)
{
    s->front=s->rear=0;   //将队首和队尾标记队列相同的位置
}

(2), determine whether the team is empty

//判断队列是否为空
int Empty(SqQueue s)
{
    if(s.front==s.rear) //因为我们在初始化的时候将它们两个相等了,所以判空直接判断
        return 1;       //为空返回真
    else
        return 0;       //不为空返回假,程序中除了0全为真
}

(3), find the length of the queue

To find the length of the queue, we first judge whether the queue is empty. If it is not empty, judge whether the rear is greater than the front. If the rear is greater than the front, it can be directly subtracted. If the rear is less than the front, the subtraction is a negative number, plus a Maxsize That is, if the subtraction is a positive number, then we can add a Maxsize and then take the remainder Maxsize. In this case, no matter whether the rear develops the front or not, we can use (s.rear-s.front+Maxsize)% Maxsize to represent

//求队列的长度
int Length(SqQueue s)
{
    //先判断队列是否为空
    if(Empty(s))     //意思是如果队列为空则返回1,那么if括号里面的意思是不等于0的话执行里面的东西
    {
        return 0;
    }
    return (s.rear-s.front+Maxsize)%Maxsize;
}

(4) Queue operation

//入队操作
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), dequeue operation

//出队操作
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), seek the first element of the team

//读取队首元素
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), the main function

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), running results

 (9), complete code

#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;
}

Summarize

       The difficulty of the circular queue is how to judge whether the queue is empty or full, and when the rear points to the last position, we will enter the queue, and when the front points to the last position, we will perform the dequeue operation, which requires a queue. Maxsize performs modulo operation. The operations of sequence table, linked list, stack, and team are very similar. You can compare them. As long as you master one of the operations, you can easily solve the other operations and internalize the logic in your heart. My ability is limited, if there is something wrong with the statement, please criticize and correct me.

Guess you like

Origin blog.csdn.net/BaoITcore/article/details/121300975