嵌入式学习-线性表-Day04-队列

时间:2024-10-10 11:33:23

队列

1 什么是队列?

只允许在两端进行插入和删除操作的线性表,在队尾插入,在队头删除 插入的一端,被称为"队尾",删除的一端被称为"队头"

在队列操作过程中,为了提高效率,以调整指针代替队列元素的移动,并将数组作为循环队列的操作空间。

2 队列的特点

先进先出 FIFO first in first out

后进后出 LILO last

循环队列顺序队列)

1逻辑结构线性结构

2存储结构顺序存储

3操作入队出队

#define N 5

typedef int datatype;

typedef struct

{

datatype data[N];

int rear; //后面,队尾

int front; //前面,队头

}sequeue_t;//sequence 顺序 queue队列

1)创建一个空的队列

2)入列

3)求长度

sequeue.c

#include <stdio.h>
#include <stdlib.h>
#define N 5
typedef int datatype;
typedef struct
{
    datatype data[N]; // 循环队列的数组
    int rear;         // 存数据端 rear 后面
    int front;        // 取数据端 front 前面
} sequeue_t;
// 1.创建一个空的队列
sequeue_t *CreateEmptySequeue()
{
    // 1.开辟一个结构体大小的空间
    sequeue_t *p = (sequeue_t *)malloc(sizeof(sequeue_t));
    if (p == NULL)
    {
        perror("CreateEmptySequeue err");
        return NULL;
    }
    // 2.初始化
    p->front = 0;
    p->rear = 0;
    return p;
}
// 3.判断队列是否为满
int IsFullSequeue(sequeue_t *p)
{
    // 判断尾巴的下一个位置是不是头
    return (p->rear + 1) % N == p->front;
}
// 2.入列 data代表入列的数据
int InSequeue(sequeue_t *p, datatype data)
{
    // 1.判满
    if (IsFullSequeue(p))
    {
        perror("IsFullSequeue");
        return -1;
    }
    // 2.数据入队
    p->data[p->rear] = data;
    // 3.移动尾下标
    p->rear = (p->rear + 1) % N;
    return 0;
}
// 4.判断队列是否为空
int IsEmptySequeue(sequeue_t *p)
{
    return p->rear == p->front;
}
// 5.出列
datatype OutSequeue(sequeue_t *p)
{
    // 1.判空
    if (IsEmptySequeue(p))
    {
        perror("IsEmptySequeue");
        return -1;
    }
    // 2.取数据
    datatype temp = p->data[p->front];
    // 3.移动队头
    p->front = (p->front + 1) % N;
    return temp;
}
// 6.求队列的长度
int LengthSequeue(sequeue_t *p)
{
    // if(p->rear >= p->front)
    //     return p->rear - p->front;
    // else
    //     return p->rear - p->front + N;

    return (p->rear - p->front + N)%N;
}
// 7.清空队列函数
void ClearSequeue(sequeue_t *p)
{
    p->front = p->rear;
}
int main(int argc, char const *argv[])
{
    sequeue_t * p = CreateEmptySequeue();
    for(int i=1;i<5;i++)
        InSequeue(p,i);
        printf("len is %d\n",LengthSequeue(p));
    while (!IsEmptySequeue(p))
        printf("%d  ",OutSequeue(p));
    printf("\n");
    free(p);
    p=NULL;
    
    return 0;
}


链式队列

1逻辑结构线性结构

  1. 存储结构链式存储
  2. 操作入队出队

typedef int datatype;

typedef struct node

{

datatype data;//数据域

struct node *next;//指针域

}linkqueue_node_t,*linkqueue_list_t;

typedef struct//将队列头指针和尾指针封装到一个结构体里

{

linkqueue_list_t front;//相当于队列的头指针

linkqueue_list_t rear;//相当于队列的尾指针

//有了链表的头指针和尾指针,那么我们就可以操作这个链表

}linkqueue_t;

(1)创建一个空的队列

(2)入列

 

(3)出列

 

#include <stdio.h>
#include <stdlib.h>
typedef int datatype;
typedef struct node
{
    datatype data;     // 数据域
    struct node *next; // 指针域
} linkqueue_node_t, *linkqueue_list_t;

// linkqueue_list_t p === linkqueue_node_t *
typedef struct // 将队列头指针和尾指针封装到一个结构体里
{
    linkqueue_list_t front; // 相当于队列的头指针
    linkqueue_list_t rear;  // 相当于队列的尾指针
    // 有了链表的头指针和尾指针,那么我们就可以操作这个链表
} linkqueue_t;
// 1.创建一个空的队列
linkqueue_t *CreateEmptyLinkQueue()
{
    // 1.开辟存放头尾指针的结构体的空间
    linkqueue_t *p = (linkqueue_t *)malloc(sizeof(linkqueue_t));
    if (p == NULL)
    {
        perror("CreateEmptyLinkQueue err");
        return NULL;
    }
    // 2.初始化:头尾指针都指向头节点
    p->front = p->rear = (linkqueue_list_t)malloc(sizeof(linkqueue_node_t));
    if (p->front == NULL)
    {
        perror("p->front malloc err");
        return NULL;
    }
    p->front->next = NULL; // 头节点的指针域为NULL,表示空
    return p;
}
// 2.入列 data代表入列的数据
int InLinkQueue(linkqueue_t *p, datatype data)
{
    // 1.开辟一个节点大小的空间存放数据
    linkqueue_list_t pnew = (linkqueue_list_t)malloc(sizeof(linkqueue_node_t));
    if (pnew == NULL)
    {
        perror("pnew malloc err");
        return -1;
    }
    pnew->data = data;
    pnew->next = NULL;
    // 2.将节点入队(尾插)
    p->rear->next = pnew;// 新节点链接到链表的尾
    // 3.移动队尾
    p->rear = pnew;// rear移动,始终指向当前链表的尾巴
    return 0;
}
// 4.判断队列是否为空
int IsEmptyLinkQueue(linkqueue_t *p)
{
    return p->front == p->rear;
}
// 3.出列
datatype OutLinkQueue(linkqueue_t *p)
{
    //1.判空
    if(IsEmptyLinkQueue(p))
    {
        perror("IsEmptyLinkQueue");
        return -1;
    }
    //2.定义pdel指向被删除节点(头节点)
    linkqueue_list_t pdel = p->front;
    //3.移动头指针
    p->front = pdel->next;
    //4.释放头节点
    free(pdel);
    pdel=NULL;
    //5.出队数据
    return p->front->data;
}

// 5.求队列长度的函数
int LengthLinkQueue(linkqueue_t *p);
// 6.清空队列
void ClearLinkQueue(linkqueue_t *p);

int main(int argc, char const *argv[])
{
    linkqueue_t *p=CreateEmptyLinkQueue();
    for(int i=1;i<=5;i++)
        InLinkQueue(p,i);
    for(int i=1;i<=5;i++)
        printf("%d ",OutLinkQueue(p));
    printf("\n");
    free(p->front);
    p->front =NULL;
    free(p);
    p=NULL;
    return 0;
}