数据结构 - 队列

一.队列的定义

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");
}
相关推荐
菜鸡中的奋斗鸡→挣扎鸡2 小时前
滑动窗口 + 算法复习
数据结构·算法
axxy20004 小时前
leetcode之hot100---240搜索二维矩阵II(C++)
数据结构·算法
Uu_05kkq5 小时前
【C语言1】C语言常见概念(总结复习篇)——库函数、ASCII码、转义字符
c语言·数据结构·算法
1nullptr7 小时前
三次翻转实现数组元素的旋转
数据结构
TT哇7 小时前
【数据结构练习题】链表与LinkedList
java·数据结构·链表
A懿轩A7 小时前
C/C++ 数据结构与算法【栈和队列】 栈+队列详细解析【日常学习,考研必备】带图+详细代码
c语言·数据结构·c++·学习·考研·算法·栈和队列
1 9 J8 小时前
数据结构 C/C++(实验五:图)
c语言·数据结构·c++·学习·算法
汝即来归9 小时前
选择排序和冒泡排序;MySQL架构
数据结构·算法·排序算法
aaasssdddd9612 小时前
C++的封装(十四):《设计模式》这本书
数据结构·c++·设计模式
芳菲菲其弥章12 小时前
数据结构经典算法总复习(下卷)
数据结构·算法