数据结构 - 队列

一.队列的定义

1.队列的分类

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

2.队列的结构

①.顺序队列

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

②.链式队列

二.顺序队列的基本运算

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

typedef int data_t;

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

1.创建一个空队列

/**
 * @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.判断队列是否为满

/**
 * @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.判断队列是否为空

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

4.入队

/**
 * @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.出队

/**
 * @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.打印队列中元素的值

/**
 * @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.链式队列的结构体定义

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.创建一个空的队列

/**
 * @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.判断队列是否为空

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

3.入队

/**
 * @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.出队

/**
 * @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.打印队列中的结点

/**
 * @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");
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值