赞
踩
队列是一种先进先出(First In First ut)的表简FIF。的一端称为队尾,允许删除的一端称为队头。假设队列是 q= ( a1,a2·....,a),那么a1 就是队头元素,而 an 是队尾元素。这样我们就可以删除时,总是从 ai 开始,而插入时,列在最后。这也比较符合我们通常生活中的习惯,排在第一个的优先出列,最后来的当然排在队伍最后, 如图所示:
队列存储结构的实现有以下两种方式:
①顺序队列:在顺序表的基础上实现的队列结构。
②链队列:在链表的基础上实现的队列结构。
两者的区别仅是顺序表和链表的区别,即在实际的物理空间中,数据集中存储的队列是顺序队列,分散存储的队列是链队列。
队列只有链式的设计方法,其本身分为多种队列,如顺序队列和循环队列,还有衍生的优先队列等等,以顺序队列的设计为例。
首先是队列的结点设计,可以设计出两个结构体,一个结构体 Node 表示结点,其中包含有 data 域和 next 指针,如图:
其中 data 表示数据,其可以是简单的类型,也可以是复杂的结构体。next 指针表示,下一个的指针,其指向下一个结点,通过 next 指针将各个结点链接。
添加一个结构体,其包括了两个分别永远指向队列的队尾和队首的指针。
InitQueue:初始化操作,建立一个空队列 Q。
DestroyQueue:若队列Q存在,则销毁它。
ClearQueue :将队列Q清空。
QueueEmpty:若队列Q为空,返回true,否则返回 false。
GetHead:若队列Q存在且非空,用e返回队列Q的队头元素。
EnQueue:若队列Q存在,插入新元素e 到队列Q中并成为队尾元素。
DeQueue:删除队列Q中队头元素,并用e返回其值。
QueueLength:返回队列Q的元素个数。
- #define OK 1
- #define ERROR 0
- #define OVERFLOW -1
- //#define MAXQSIZE 100 //最大队列长度
- typedef int Status;
- const int MaxQSize = 100;
- typedef int ElemType;
- typedef struct
- {
- ElemType* base; //初始化的动态分配存储空间
- int front; //头指针,若队列不空,指向队列头元素
- int rear; //尾指针,若队列不空,指向队列尾元素的下一个位置
- int cursize; //循环队列元素的个数, 为0时队列空,当cursize == MAXQSIZE 时队列满
- int maxsize;
- }SeqQueue;
-
- //构造一个空队列
- Status InitQueue(SeqQueue* pe)
- {
- assert(pe != nullptr);
- pe->base = (ElemType*)malloc(sizeof(ElemType) * MaxQSize);
- if (nullptr == pe->base)
- {
- exit(EXIT_FAILURE);
- }
- pe->cursize = 0;
- pe->front = 0;
- pe->rear = 0;
- pe->maxsize = MaxQSize;
- return OK;
- }
-
- //销毁队列,不再存在
- void DestroyQueue(SeqQueue* pe)
- {
- assert(pe != nullptr);
- free(pe->base);
- pe->base = nullptr;
- pe->front = pe->rear = pe->cursize = pe->maxsize = 0;
- }
-
- //将队列清为空
- void ClearQueue(SeqQueue* pe)
- {
- assert(pe != nullptr);
- pe->cursize = 0;
- pe->front = 0;
- pe->rear = 0;
-
- }
-
- //返回队列的元素个数,即为队列的长度
- int QueueLength(const SeqQueue* pe)
- {
- assert(pe != nullptr);
- return pe->cursize;
- }
-
- //检查循环队列是否为空
- bool IsEmpty(const SeqQueue* pe) {
- assert(pe != nullptr);
- return pe->cursize == 0;
- }
-
- // 检查循环队列是否已满。
- bool IsFull(const SeqQueue* pe) {
- assert(pe != nullptr);
- return pe->cursize == pe->maxsize;
- }
-
- //若队列不空,则用pval返回队头元素,并返回OK;否则返回ERROR
- Status GetHead(const SeqQueue* pe, ElemType* pval)
- {
- assert(pe != nullptr && pval != nullptr);
- if (IsEmpty(pe))
- {
- return ERROR;
- }
- *pval = pe->base[pe->front];
- return OK;
- }
-
- //若队列不空,则用pval返回的队尾元素,并返回OK;否则返回ERROR
- Status GetTail(const SeqQueue* pe, ElemType* pval)
- {
- assert(pe != nullptr && pval != nullptr);
- if (IsEmpty(pe))
- {
- return ERROR;
- }
- int rindex = pe->rear - 1;
- if (rindex < 0) rindex = pe->maxsize - 1;
- }
-
- //队尾插入元素val, val为新的队尾元素
- Status EnQueue(SeqQueue* pe, ElemType val)
- {
- assert(pe != nullptr);
- if (IsFull(pe))
- {
- return ERROR;
- }
- pe->base[pe->rear] = val;
- pe->rear = (pe->rear + 1) % pe->maxsize;
- pe->cursize += 1;
- return OK;
- }
-
- //若队列不空,则删除队头元素,用pval返回其值,并返回0K,否则返回ERROR
- Status DeQueue(SeqQueue* pe, ElemType* pval)
- {
- assert(pe != nullptr && pval != nullptr);
- if (IsEmpty(pe))
- {
- return ERROR;
- }
- *pval = pe->base[pe->front];
- pe->front = (pe->front + 1) % pe->maxsize;
- return OK;
- }
- int main()
- {
- SeqQueue seq;
- InitQueue(&seq);
-
- DestroyQueue(&seq);
- return 0;
- }

用链表表示的队列简称为链队列。一个链队列显然需要两个分别指示队头和队尾的指针(分别称为头指针和尾指针)才能惟一确定。这里,和线性表的单链表一样,为了操作方便起见,我们也给链队列添加一个头结点,并令头指针指向头结点。 由此,空的链队列的判决条件为头指针和尾指针均指向头结点。
- #include <stdio.h>
- #include <stdlib.h>
- #include <assert.h>
-
-
-
- #define OK 0
- #define ERROR -1
- typedef int Status;
- typedef int QElemType;
- typedef struct QNode
- {
- QElemType data;
- struct QNode* next;
- }QNode, * QueuePtr;
- typedef struct
- {
- QueuePtr front; // 对头指针
- QueuePtr rear; // 队尾指针
- int cursize; // 元素个数
- }LinkQueue;
-
- QNode* Buynode(QElemType val, QNode* narg = nullptr) //购买节点 数据域 next域
- {
- QNode* s = (QNode*)malloc(sizeof(QNode)); //购买QNode结点
- if (nullptr == s) //malloc不一定成功
- {
- exit(EXIT_FAILURE); // _exit; abort(); exit终止当前的进程
- }
- s->data = val;
- s->next = narg;
- return s;
- }
- void Freenode(QNode* p)
- {
- assert(p != nullptr);
- free(p); //释放结点
- }
-
- //构造一个空队列
- Status InitQueue(LinkQueue* pe)
- {
- assert(pe != nullptr);
- pe->cursize = 0;
- pe->front = pe->rear = Buynode(0);
- return OK;
- }
- //将队列清为空
- void ClearQueue(LinkQueue* pe)
- {
- assert(pe != nullptr);
- while (pe->front->next != nullptr)
- {
- QNode* q = pe->front->next;
- pe->front->next = q->next;
- Freenode(q);
- }
- }
-
- //销毁队列,不再存在
- void DestroyQueue(LinkQueue* pe)
- {
- assert(pe != nullptr);
- ClearQueue(pe);
- Freenode(pe->front);
- pe->front = pe->rear = nullptr;
- }
-
-
- //返回队列的元素个数,即为队列的长度
- int QueueLength(const LinkQueue* pe)
- {
- assert(pe != nullptr);
- return pe->cursize;
- }
-
- //检查队列是否为空
- bool IsEmpty(const LinkQueue* pe)
- {
- assert(pe != nullptr);
- return pe->cursize == 0;
-
- }
- //若队列不空,则用pval返回队头元素,并返回OK;否则返回ERROR
- Status GetHead(const LinkQueue* pe, QElemType* pval)
- {
- assert(pe != nullptr);
- if (IsEmpty(pe))
- {
- return ERROR;
- }
- *pval = pe->front->next -> data;
- return OK;
- }
-
- //若队列不空,则删除队头元素,用pval返回其值,并返回0K,否则返回ERROR
- Status DeQueue(LinkQueue* pe, QElemType* pval)
- {
- assert(pe != nullptr && pval != nullptr);
- if (IsEmpty(pe))
- {
- return ERROR;
- }
- QNode* q = pe->front->next; // first;
- *pval = q->data;
- pe->front->next = q->next;
- Freenode(q);
- pe->cursize -= 1;
- if (pe->cursize == 0)
- {
- pe->rear = pe->front;
- }
- return OK;
- }
-
- int main()
- {
- LinkQueue myq;
- InitQueue(&myq);
-
- int x;
- while (!IsEmpty(&myq))
- {
- DeQueue(&myq, &x);
- printf("%d\n", x);
- }
-
- DestroyQueue(&myq);
- return 0;
- }

Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。