队列操作

前面学习了基于顺序表以及链式表的堆栈操作,这里的链式表指单向链表,这篇文章学习同样是基于顺序表以及链式表的队列操作。

队列与堆栈的不同之处在于队列是先进先出,即队列的两边都可以进行操作,一头压入,另一头弹出。这就需要用到头指针和尾指针两个指针,为了避免指针指向空的内存,因此这两个头尾指针可以循环,而且当队列处于空或者满状态的时候,头尾指针均可能重合。

基于顺序表的实现,初始化空间,操作前端和后端两个指针,前端指针负责弹出,后端指针负责压入,并且循环使用存储空间,判断空和满。

在进程等待的时候就是将进程先放入消息队列中,先进来先进行处理,这也是一个队列的实现。

队列的操作其实和前面的堆栈很像,下面就用程序来实现一下队列的操作
基于顺序表的队列

头文件

/********************************************************************************
 *      Copyright:  (C) 2017 tangyanjun<519656780@qq.com>
 *                  All rights reserved.
 *
 *       Filename:  order.h
 *    Description:  This head file 
 *
 *        Version:  1.0.0(07/24/2017)
 *         Author:  tangyanjun <519656780@qq.com>
 *      ChangeLog:  1, Release initial version on "07/24/2017 09:25:50 AM"
 *                 
 ********************************************************************************/
#ifndef _ORDER_H
#define _ORDER_H

#include <stdio.h>
#include <sys/types.h>
#include <stdbool.h>
#include <stdlib.h>


typedef struct Queue{
    int*   arr;  /* 数组 */
    size_t cap;  /* 容量 */
    size_t front;/* 前端弹出 */
    size_t rear; /* 后端压入 */
    size_t size; /* 大小 */
} QUEUE;


/* 分配内存并初始化为空队列 */
void queue_init(QUEUE* queue, size_t cap);
/* 释放内存并恢复到初始状态 */
void queue_deinit(QUEUE* queue);
/* 判断是否满 */
bool queue_full(QUEUE* queue);
/* 判断是否空 */
bool queue_empty(QUEUE* queue);
/* 压入 */
void queue_push(QUEUE* queue, int data);
/* 弹出 */
int queue_pop(QUEUE* queue);
/* 队首 */
int queue_front(QUEUE* queue);
/* 大小 */
size_t queue_size(QUEUE* queue);



#endif /* _ORDER_H */

C文件

/********************************************************************************
 *      Copyright:  (C) 2017 tangyanjun<519656780@qq.com>
 *                  All rights reserved.
 *
 *       Filename:  order.h
 *    Description:  This head file 
 *
 *        Version:  1.0.0(07/24/2017)
 *         Author:  tangyanjun <519656780@qq.com>
 *      ChangeLog:  1, Release initial version on "07/24/2017 09:25:50 AM"
 *                 
 ********************************************************************************/
#include "order.h"

/* 分配内存并初始化为空队列 */
void queue_init(QUEUE* queue, size_t cap)
{
    queue->arr = malloc(cap * sizeof(queue->arr[0]));  //为数组分配内存空间大小
    queue->cap = cap;  //容量
    queue->rear = 0;
    queue->front = 0;
    queue->size = 0;
}
/* 释放内存并恢复到初始状态 */
void queue_deinit(QUEUE* queue)
{
    free(queue->arr);
    queue->arr = NULL;
    queue->cap = 0;
    queue->front = 0;
    queue->rear = 0;
    queue->size = 0;
}
/* 判断是否满 */
bool queue_full(QUEUE* queue)
{
    return queue->size >= queue->cap;
}
/* 判断是否空 */
bool queue_empty(QUEUE* queue)
{
    return !queue->size;
}
/* 压入 */
void queue_push(QUEUE* queue, int data)   //满了不能压
{
    if(queue->rear >= queue->cap)
    {
        queue->rear = 0;
    }
    ++queue->size;
    queue->arr[queue->rear++] = data;
}
/* 弹出 */
int queue_pop(QUEUE* queue)
{
    if(queue->front >= queue->cap)   //空了不能弹
    {
       queue->front = 0;
    }
    --queue->size;
    return queue->arr[queue->front++];
}
/* 队首 */
int queue_front(QUEUE* queue)
{
    if(queue->front >= queue->cap)
    {
        queue->front = 0;
    }
    return queue->arr[queue->front];
}
/* 大小 */
size_t queue_size(QUEUE* queue)
{
    return queue->size;
}




测试程序:

/*********************************************************************************
 *      Copyright:  (C) 2017 tangyanjun<519656780@qq.com>
 *                  All rights reserved.
 *
 *       Filename:  otest.c
 *    Description:  This file 
 *                 
 *        Version:  1.0.0(07/24/2017)
 *         Author:  tangyanjun <519656780@qq.com>
 *      ChangeLog:  1, Release initial version on "07/24/2017 09:45:15 AM"
 *                 
 ********************************************************************************/
#include "order.h"

int main(int argc, char **argv)
{
    QUEUE queue;
    queue_init(&queue, 9);
    int i = 0;

    for (i = 10; i <= 50; i+=10)
    {
        if (!queue_full(&queue))
        {
            queue_push(&queue, i);
        }
    }

    for (i = 0; i < 2; ++i)
    {
        if (!queue_empty(&queue))
        {
            printf("%d\n", queue_pop(&queue));
        }
    }

    for (i = 50; i <= 80; i+=10)
    {
        if (!queue_full(&queue))
        {
            queue_push(&queue, i);
        }
    }

    while(!queue_empty(&queue))
    {
        printf("%d\n", queue_pop(&queue));
    }

    queue_deinit(&queue);

    return 0;
}

结果:

[tangyanjun@VM_216_80_centos queue]$ gcc order.c otest.c 
[tangyanjun@VM_216_80_centos queue]$ a.out 
10
20
30
40
50
50
60
70
80

由此可见队列先进先出的特点

基于链表的队列

头文件:

/********************************************************************************
 *      Copyright:  (C) 2017 tangyanjun<519656780@qq.com>
 *                  All rights reserved.
 *
 *       Filename:  lq.h
 *    Description:  This head file 
 *
 *        Version:  1.0.0(07/24/2017)
 *         Author:  tangyanjun <519656780@qq.com>
 *      ChangeLog:  1, Release initial version on "07/24/2017 09:25:50 AM"
 *                 
 ********************************************************************************/
#ifndef _LQ_H
#define _LQ_H

#include <stdio.h>
#include <sys/types.h>
#include <stdbool.h>
#include <stdlib.h>

typedef struct QueueNode{
    int                 data; //数据
    struct QueueNode*   next; //后指针
} QUEUE_NODE;

typedef struct Queue{
    QUEUE_NODE* front;  //弹出,前端
    QUEUE_NODE* rear;   //压入,后端
} QUEUE;


/* 分配内存并初始化为空队列 */
void queue_init(QUEUE* queue);
/* 释放剩余节点并恢复到初始状态 */
void queue_deinit(QUEUE* queue);
/* 判断是否空 */
bool queue_empty(QUEUE* queue);
/* 压入 */
void queue_push(QUEUE* queue, int data);
/* 弹出 */
int queue_pop(QUEUE* queue);
/* 队首 */
int queue_front(QUEUE* queue);
/* 大小 */
size_t queue_size(QUEUE* queue);



#endif /* _LQ_H */

C文件

/********************************************************************************
 *      Copyright:  (C) 2017 tangyanjun<519656780@qq.com>
 *                  All rights reserved.
 *
 *       Filename:  lq.c
 *    Description:  This head file 
 *
 *        Version:  1.0.0(07/24/2017)
 *         Author:  tangyanjun <519656780@qq.com>
 *      ChangeLog:  1, Release initial version on "07/24/2017 09:25:50 AM"
 *                 
 ********************************************************************************/
#include "lq.h"

/* 创建节点 */
static QUEUE_NODE* create_node(int data)
{
    QUEUE_NODE* node = malloc(sizeof(QUEUE_NODE));
    node->data = data;
    node->next = NULL;
    return node;
}
/* 销毁节点 */
static QUEUE_NODE* destroy_node(QUEUE_NODE* node)
{
    QUEUE_NODE* next = node->next;
    free(node);
    return next;
}

/* 初始化为空队列 */
void queue_init(QUEUE* queue)
{
    queue->front = NULL;
    queue->rear = NULL;
}

/* 释放剩余节点并恢复到初始状态 */
void queue_deinit(QUEUE* queue)
{
    while(queue->front)
    {
        queue->front = destroy_node(queue->front);
    }
    queue->rear = NULL;
}
/* 判断是否空 */
bool queue_empty(QUEUE* queue)
{
    return !queue->front && !queue->rear;
}
/* 压入 */
void queue_push(QUEUE* queue, int data)
{
    QUEUE_NODE* node = create_node(data);
    if (queue->rear)
    {
        queue->rear->next = node;
    }
    else
    {
        queue->front = node;
    }
    queue->rear = node;
}
/* 弹出 */
int queue_pop(QUEUE* queue)
{
    int data = queue->front->data;
    if (!(queue->front = destroy_node(queue->front)))
    {
        queue->rear = NULL;
    }
    return data;
}
/* 队首 */
int queue_front(QUEUE* queue)
{
    return queue->front->data;
}
/* 大小 */
size_t queue_size(QUEUE* queue)
{
    size_t size = 0;
    QUEUE_NODE* node = NULL;
    for (node = queue->front; node; node = node->next)
    {
        ++size;
    }
    return size;
}




测试程序

/*********************************************************************************
 *      Copyright:  (C) 2017 tangyanjun<519656780@qq.com>
 *                  All rights reserved.
 *
 *       Filename:  lqtest.c
 *    Description:  This file 
 *                 
 *        Version:  1.0.0(07/24/2017)
 *         Author:  tangyanjun <519656780@qq.com>
 *      ChangeLog:  1, Release initial version on "07/24/2017 10:46:52 AM"
 *                 
 ********************************************************************************/
#include <string.h>
#include <stdlib.h>
#include "lq.h"

int main(int argc, char **argv)
{
    QUEUE queue;
    queue_init (&queue);
    char text[20];

    for(;;)
    {
        fgets(text, 20, stdin);
        if (strcmp(text, "!") == 0)
        {
            break;
        }
        queue_push(&queue, (int)strcpy(malloc((strlen(text) + 1) * sizeof(char)), text));
    }
    printf("-----------------\n");
    while(!queue_empty(&queue))
    {
        char* ps = (char*)queue_pop(&queue);
        printf("%s\n", ps);
        free(ps);
    }
    queue_deinit(&queue);
    return 0;
}

当我们输入“!”时,输入结束,屏幕按队列顺序打印出我们的输入。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值