数据结构 - 队列

一.队列的定义

1.队列的分类

队列根据存储结构可以分为 顺序队列链式队列

2.队列的结构

①.顺序队列

顺序队列的 front 指向队首元素的前一个下标

②.链式队列

二.顺序队列的基本运算

0.顺序队列的结构体定义

cpp 复制代码
typedef int data_t;

typedef struct 
{
    data_t *data;                     //用数组作为队列的存储空间
    int front,rear;                 // front 为队头前一个位置的下标 , rear 为队列尾部的下标
}sequeue_t;

1.创建一个空队列

cpp 复制代码
/**
 * @description:            创建一个空队列
 * @param -         :       无
 * @return          :       创建的队列的指针
*/
sequeue_t *Sequeue_Create(void)
{
    sequeue_t *q;

    /* 1.为队列分配空间 */
    q = (sequeue_t *)malloc(sizeof(sequeue_t));
    if(NULL == q)
    {
        printf("malloc error!\n");
        return NULL;
    }

    /* 2.初始化 front 和 rear 都为 MAXSIZE - 1 */
    q->front = q->rear = MAXSIZE - 1;

    return q;
}

2.判断队列是否为满

cpp 复制代码
/**
 * @description:            判断队列是否为满
 * @param - q       :       要操作的队列的指针
 * @return          :       1为满,0为非满
*/
int Sequeue_Is_Full(sequeue_t *q)
{
    if((q->rear + 1) % MAXSIZE == q->front)
        return 1;
    else
        return 0;
}

3.判断队列是否为空

cpp 复制代码
/**
 * @description:            判断队列是否为空
 * @param - q       :       要操作的队列的指针
 * @return          :       1为空,其他为非空
*/
int Sequeue_Is_Empty(sequeue_t *q)
{
    if(q->rear == q->front)
        return 1;
    else
        return 0;
}

4.入队

cpp 复制代码
/**
 * @description:                入队
 * @param - q       :           指向队列的指针
 * @param - value   :           入队元素的值
 * @return          :           0为成功,其他为失败
*/
int Sequeue_In(sequeue_t *q,data_t value)
{
    /* 1.先看队列是否已满 */
    if(Sequeue_Is_Full(q))
    {
        printf("queue is already full!\n");
        return -1;
    }

    /* 2.入队,rear 向后移动,(q->rear+1)%MAXSIZE 是为了保证数组不越界,使该队列成为循环队列 */
    q->rear = (q->rear + 1) % MAXSIZE;

    /* 3.写入数据 */
    q->data[q->rear] = value;

    return 0;
}

5.出队

cpp 复制代码
/**
 * @description:            出队
 * @param - q       :       要操作的队列的指针
 * @param - data    :       用于存储出队的元素的值
 * @return          :       0为成功,其他为失败
*/
int Sequeue_Out(sequeue_t *q,data_t *data)
{
    /* 1.判断队列是否为空 */
    if(Sequeue_Is_Empty(q))
    {
        printf("sequeue is already empty!\n");
        return -1;
    }

    /* 2.出队 */
    q->rear = (q->rear + 1) % MAXSIZE;
    *data = q->data[q->front];

    return 0;
}

6.打印队列中元素的值

cpp 复制代码
/**
 * @description:            打印出队列所有元素的值
 * @param - q       :       要操作的队列的指针
*/
void Show_Sequeue(sequeue_t *q)
{
    int i = 0;

    /* 1.若为空,则退出 */
    if(Sequeue_Is_Empty(q))
        return ;

    /* 2.遍历打印队列中的元素 */
    for(i = (q->front+1)%MAXSIZE ; i != (q->rear+1)%MAXSIZE ; i = (i+1)%MAXSIZE)
    {
        printf("%d\t",q->data[i]);
    }
    
    printf("\n");
}

三.链式队列的基本运算

0.链式队列的结构体定义

cpp 复制代码
typedef int data_t;


/* 1.链表结点 */
typedef struct node
{
    data_t data;                    //结点的数据域
    struct node *next;              //指向下一个结点的指针

}link_node;

/* 2.队列的队头和队尾指针 */
typedef struct
{
    link_node *front,*rear;             //front 指向队头元素的前一个结点(即链表的首结点) , rear 指向队尾结点

} linkqueue_t;

1.创建一个空的队列

cpp 复制代码
/**
 * @description:                创建一个空队列
 * @param           :           无
 * @return          :           队列的首结点指针
*/
linkqueue_t *Linkqueue_Create(void)
{
    linkqueue_t *q;

    /* 1.申请队列 front 和 rear 的空间 */
    q = (linkqueue_t *)malloc(sizeof(linkqueue_t));
    if(NULL == q)
    {
        printf("malloc error!\n");
        return NULL;
    }


    /* 2.申请链表中头结点的空间 */
    q->front = (link_node *)malloc(sizeof(link_node));
    if(NULL == q->front)
    {
        printf("malloc error!\n");
        return NULL;
    }
    
    q->front->next = NULL;              //初始化链表首结点的 next = NULL
    q->rear = q->front;                 //初始化 front 和 rear 都指向链表首结点

    return q;
}

2.判断队列是否为空

cpp 复制代码
/**
 * @description:            判断队列是否为空
 * @param - q       :       要操作的队列的指针
 * @return          :       1为空 , 0为非空
*/
int Linkqueue_is_empty(linkqueue_t *q)
{
    return (q->front == q->rear ? 1 : 0);
}

3.入队

cpp 复制代码
/**
 * @description:            入队
 * @param - q       :       要操作的队列的指针
 * @param - value   :       要入队的元素的值
 * @return          :       0为成功,其他为失败
*/
int Linkqueue_In(linkqueue_t *q,data_t value)
{
    link_node *p;               //指向新创建的结点

    /* 1.创建新的结点 */
    p = (link_node *)malloc(sizeof(link_node));
    if(NULL == p)
    {
        printf("malloc error!\n");
        return -1;
    }
        
    /* 2.初始化新结点 */
    p->data = value;
    p->next = NULL;

    /* 3.向链表进行尾插以实现入队 */
    q->rear->next = p;
    q->rear = p;

    return 0;

}   

4.出队

cpp 复制代码
/**
 * @description:            出队 , 使用前需判断队列是否为空
 * @param - q       :       要操作的队列的指针
 * @param - value   :       保存出队的元素的值
 * @return          :       无
*/
void Linkqueue_Out(linkqueue_t *q,data_t *value)
{
    link_node *p;           //用来指向队头元素的前一个结点

    /* 1. p 指向队头的前一个结点( front 就指向了队头元素的前一个结点 ) */
    p = q->front;

    /* 2. front 向后移动 */
    q->front = q->front->next;

    /* 3.保存要出队的值 */
    *value = q->front->data;

    /* 4.释放 p */
    free(p);

}

5.打印队列中的结点

cpp 复制代码
/**
 * @description:            打印队列中的数据
 * @param - q       :       要操作的队列的指针
 * @return          :       无
*/
void Linkqueue_Show(linkqueue_t *q)
{
    link_node  *p;      //用于指向当前链表的结点

    /* 从队头开始遍历打印 */
    for(p = q->front->next ; p != NULL ; p = p->next)
    {
        printf("%d ",p->data);
    }
    printf("\n");
}
相关推荐
CV工程师小林14 分钟前
【算法】BFS 系列之边权为 1 的最短路问题
数据结构·c++·算法·leetcode·宽度优先
Navigator_Z38 分钟前
数据结构C //线性表(链表)ADT结构及相关函数
c语言·数据结构·算法·链表
还听珊瑚海吗39 分钟前
数据结构—栈和队列
数据结构
Aic山鱼43 分钟前
【如何高效学习数据结构:构建编程的坚实基石】
数据结构·学习·算法
sjsjs111 小时前
【数据结构-一维差分】力扣1893. 检查是否区域内所有整数都被覆盖
数据结构·算法·leetcode
Lzc7741 小时前
堆+堆排序+topK问题
数据结构·
cleveryuoyuo2 小时前
二叉树的链式结构和递归程序的递归流程图
c语言·数据结构·流程图
湫兮之风2 小时前
c++:tinyxml2如何存储二叉树
开发语言·数据结构·c++
zhyhgx3 小时前
【算法专场】分治(上)
数据结构·算法
Joeysoda3 小时前
Java数据结构 时间复杂度和空间复杂度
java·开发语言·jvm·数据结构·学习·算法