数据结构之守规矩的先进先出的队列(二)

Posted on 2018-10-28 16:35  时光top  阅读(489)  评论(0编辑  收藏  举报

一、队列的概念

  队列是一种特殊的线性表,严格按照“先进先出”的原则。

二、队列基础

  队列和栈一样只允许在断点处插入和删除元素,其基本操作包括以下:

  (1)InitQueue(&Q);    //初始化一个空队列

  (2)DestroyQueue(&Q);   //清空队列

  (3)QueueEmpty(&Q);  //队列判空

  (4)QueueLength(&Q); //求队列的长度

  (5)GetHead(Q,&e); //取对头元素

  (6)EnQueue(&Q,e); //插入新元素

  (7)DeQueue(&Q,&e); //删除队头元素

  (8)QueueTraverse(Q,visit()); //每个元素调用visit()函数

  队列的分类:链队列和循环队列

  C语言定义链队的格式

typedef struct QNode
{
    ElemType data;
    struct Qnode *next;
}QNode,*QueuePtr;
typedef struct
{
    QueuePtr front;  //对头指针,指向头元素
    QueuePtr rear;   //队尾指针,指向队尾元素
}LinkQueue;

   可以采用顺序表来存储定义循环队列,具体代码如下:

#define MAXQSIZE 100    //最长队列长度
typedef struct {
    ElemType *base;     //存储空间
    int front;          //头指针,指向队列的头元素
    int rear;           //尾指针,指向队列元素的下一个位置
}SqQueue;

   队列的基本操作

  (1)初始化队列Q的目的是创建一个队列

void InitQueue(QUEUE *Q)
{
    Q->front = -1;
    Q->rear = -1;
}

   (2)入队的目的是将一个新元素添加到队尾,相当于队列最后队列等候。

void EnQueue(QUEUE *Q, Elemtype elem){
    if ((Q->rear+1)%MAX_QUEUE==Q->front)
    {
        exit(OVERFLOW);
    }
    else{
        Q->rear = (Q->reasr + 1) % MAX_QUEUE;
        Q->elem[Q->rear] = elem;
    }
}

  (3)出队的目的是取出对头元素,并同时删除该元素,使后一个元素成为对头元素。

void DeQueue(QUEUE *Q, Elemtype *elem)
{
    if (QueueEmpty(*Q))
    {
        exit("Queue is empty.");
    }
    else
    {
        Q->front = (Q->front + 1) % MAX_QUEUE;
        *elem = Q->elem[Q->front];
    }
}

  (4)获取队列的第一个元素,即将队头的元素取出,不删除该元素,队头仍然是该元素。

void GetFront(QUEUE *Q, Elemtype *elem)
{
    if (QueueEmpty(*Q))
    {
        exit("Queue is empty.");
    }
    else
    {
        *elem = Q->elem[ (Q->front + 1) % MAX_QUEUE];
    }
}

  (5)判断队列Q是否为空

int QueueEmpty(Queue Q)
{
    if (Q.front==Q.rear)
    {
        return TRUE;
    }
    else
    {
        return FALSE;
    }
}

  队列的链式存储

  在C语言中,链式队列的基本操作算法如下:

  (1)初始化队列Q,算法代码如下:

void InitQueue(QUEUE *Q)
{
    Q->front = (LINKLIST*)malloc(sizeof(LINKLIST));
    if (Q->front==NULL) 
    {
        exit(ERROR);
    }
    Q->rear = Q->front;
}

  (2)入队操作

void EnQueue(QUEUE *Q, Elemtype elem){
    s = (LINKLIST*)malloc(sizeof(LINKLIST));
    if (!s)
    {
        exit(ERROR);
    }
    s->elem = elem;
    s->next = NULL;
    Q->rear->next = s;
    Q->rear = s;
}

  (3)出队操作

void DeQueue(QUEUE *Q, Elemtype *elem)
{
    if (QueueEmpty(*Q))
    {
        exit(ERROR);
    }
    else
    {
        *elem = Q->front->next->elem;
        s = Q->front->next;
        Q->front->next = s->next;
        Q->front = (Q->front + 1) % MAX_QUEUE;
        free(s);
    }
}

  (4)获取队头元素

void GetFront(QUEUE Q, Elemtype *elem)
{
    if (QueueEmpty(Q))
    {
        exit(ERROR);
    }
    else
    {
        *elem = Q->front->next->elem;
    }
}

   (5)判断队列Q是否为空

void QueueEmpty(QUEUE Q)
{
    if (Q->front==Q->rear)
    {
        return TRUE;
    }
    else
    {
        return FALSE;
    }
}

 三、实例演练

  “新增顾客”编号问题

  代码实现:

/*
    构建一个完整循环队列
*/
#include "stdio.h"
#include "malloc.h"
#define QUEUEMAX 15
//typedef DATA;
typedef struct  
{
    DATA data[QUEUEMAX]; //队列数组
    int head;
    int tail;
}CycQueue;
CycQueue *CycQueueInit()
{
    CycQueue *q;
    if (q=(CycQueue *)malloc(sizeof(CycQueue)))
    {
        q->head = 0;//设置队头
        q->tail = 0;//设置队尾
        return q;
    }
    else
    {
        return NULL;//返回空
    }
}

void CycQueueFree(CycQueue *q)  //释放队列
{
    if (q!=NULL)  
        free(q);
}

int CycQueueIsEmpty(CycQueue *q) //队列是否为空
{
    return (q->head == q->tail);
}

int CycQueueIsFull(CycQueue *q)  //队列是否为满
{
    return ((q->tail + 1) % QUEUEMAX == q->head);
}

int CycQueueIn(CycQueue *q, DATA data) //入队
{
    if ((q->tail + 1) % QUEUEMAX == q->head)
    {
        printf("队列满了!\n");
        return 0;
    }
    else
    {
        q->tail = (q->tail + 1) % QUEUEMAX;//求列尾序号
        q->data[q->tail] = data;
        return 1;
    }
}

DATA *CycQueueOut(CycQueue *q)  //循环队列出队函数
{
    if (q->head==q->tail)  //队列为空
    {
        printf("队列为空了!\n");
        return NULL;
    }
    else
    {
        q->head = (q->head + 1) % QUEUEMAX;
        return &(q->data[q->head]);
    }
}

int CycQueueLen(CycQueue *q)  //获取队列长度
{
    int n;
    n = q->tail - q->head;
    if (n<0)
    {
        n = QUEUEMAX + n;
    }
    return n;
}

DATA *CycQueuePeek(CycQueue *q) //获取队列第一个位置的数据
{
    if (q->head==q->tail)
    {
        printf("队列已经空了!\n");
        return NULL;
    }
    else
    {
        return &(q->data[(q->head + 1) % QUEUEMAX]);
    }
}


##############################################
#include "stdlib.h"
#include "stdio.h"
#include "time.h"
#include "xuncao.h"

typedef struct 
{
    int num;    //顾客编号
    long time;  //进入队列的时间

}DATA;

int num;  //顾客序号
void add(CycQueue *q) //新增顾客排列
{
    DATA data;
    if (!CycQueueIsFull(q))
    {
        data.num = ++num;
        data.time = time(NULL);
        CycQueueIn(q, data);
    }
    else
    {
        printf("\n排队的人实在是太多了,请您稍候再排队!\n");
    }
}

void next(CycQueue *q)  //通知下一位顾客准备
{
    DATA *data;
    if (!CycQueueIsEmpty(q))  //若队列不为空
    {
        data = CycQueueOut(q); //取队列头部的数据
        printf("\n欢迎编号为%d的顾客到柜台办理业务!\n", data->num);
    }
    if (!CycQueueIsEmpty(q))  //若队列不为空
    {
        data = CycQueuePeek(q); //取队列中指定位置的数据
        printf("请编号为%d的顾客做好准备,马上将为您办理业务!\n", data->num);
    }
}

int main()
{
    CycQueue *queuel;
    int i, n;
    char select;
    num = 0;  //顾客序号
    queuel = CycQueueInit();//初始化队列
    if (queuel==NULL)
    {
        printf("创建队列时出错误!\n");
        getch();
        return 0;
    }
    do 
    {
        printf("\n请选择具体操作:\n");
        printf("1.新到顾客\n");
        printf("2.下一个顾客\n");
        printf("0.退出\n");
        fflush(stdin);
        select = getch();
        switch (select)
        {
        case'1':
            add(queuel);
            printf("\n现在共有%d位顾客在等候!\n", CycQueueLen(queuel));
            break;
        case'2':
            next(queuel);
            printf("\n现在共有%d位顾客在等候!\n", CycQueueLen(queuel));
            break;
        case'0':
            break;
        }

    } while (select!='0');
    CycQueueFree(queuel); //释放队列
    system("pause");
    return 0;
}
代码实现

 

Copyright © 2024 时光top
Powered by .NET 8.0 on Kubernetes