看数据结构写代码(16)顺序队列的实现(循环队列)

循环队列的基本结构如下:

front 属性 表示 队头,rear 属性表示 队尾。

在队空时 :q.rear 和 q.front 都为0 ,其余时刻q.rear 指向 队尾的后继节点,q.front指向 队头.

当在队尾插入元素时,q.rear + 1 ,在删除 队头元素时 ,q.front + 1,这样的操作 会造成 “假溢出”问题。

图(d) 就是一种 假溢出 问题,q.rear 指向 空间的边界,再插入 会造成 溢出,但是 实际上 空间 并未满。

为了解决假溢出,将 队列 看成 一个 环。下面上图:

当队列成为一个循环队列时 有两个问题:

1. 当队空 和 队满时, q.front 都等于 q.rear;这样就无法区分 队空 和 队满的 情况。解决这个问题 有两个方法:

(1) 设置 一个 标志位,来区分 是队空,还是队满。

(2) 少用一个元素空间(最高地址元素),判断 队头指针在 队尾指针的下一个位置上就是队满。

下面的代码用的是第一个方法,设置了一个 队列长度 len 属性 来 判断 队空,队满。

2. 当 队满时,不能像 顺序表一样 重新 分配 一个更大的 空间。所以 如果 不知道 队列的 最大空间,请 使用 链表,或者 非循环队列。非循环队列 在出队时, 队头位置不动,,而是移动元素位置,并将 队尾位置减1.

下面贴出我的代码,欢迎指出代码不足

// SequenceQueue.cpp : 循环队列的算法实现。//#include "stdafx.h"#include <stdlib.h>////队列最大分配数#define QUEUE_MAX_SIZE10//为了测试 故意将值设置很小typedef int ElementType;enum E_State{E_State_Error = 0,E_State_Ok,};//循环队列数据结构struct Queue{ElementType * base;//堆分配基址int front;//队头索引,指向队头节点int rear;//队尾索引,指向队尾节点的后继结点int len;//队长};E_State queueInit(Queue * queue){queue->base = (ElementType *) malloc(sizeof(ElementType) * QUEUE_MAX_SIZE);if (queue->base != NULL){queue->front = queue->rear = 0;queue->len = 0;return E_State_Ok;}else{return E_State_Error;}}void queueClear(Queue * q){q->front = q->rear = 0;q->len = 0;}void queueDestory(Queue * q){queueClear(q);free(q->base);q->base = NULL;}bool queuEmpty(Queue q){return q.len == 0 ? true : false;}int queueLen(Queue q){return q.len;}//入队E_State enqueue(Queue * q,ElementType data){if (q->len >= QUEUE_MAX_SIZE){printf("队满,插入无效\n");return E_State_Error;}q->base[q->rear] = data;q->rear = (q->rear +1)% QUEUE_MAX_SIZE;q->len++;return E_State_Ok;}//出队E_State dequeue(Queue * q,ElementType * data){if (q->len > 0)//栈不为空{*data = q->base[q->front];q->front = (q->front + 1) % QUEUE_MAX_SIZE;q->len –;return E_State_Ok;}return E_State_Error;}void queueTraverse(Queue q){printf("——–队列遍历开始———-\n");if (q.len > 0)//队列非空{int index = q.front;//用do while 排除了 队满的情况。。。do{printf("———-%d———–\n",q.base[index]);index = (index+1)%QUEUE_MAX_SIZE;} while (index != q.rear);}printf("——–队列遍历结束———-\n");}int _tmain(int argc, _TCHAR* argv[]){Queue queue;queueInit(&queue);//初始化enqueue(&queue,1);//入队ElementType data;dequeue(&queue,&data);//出队for (int i = 1; i <= QUEUE_MAX_SIZE+1; i++)//故意入满,还入队{enqueue(&queue,i);}dequeue(&queue,&data);dequeue(&queue,&data);//出队queueTraverse(queue);char * s = queuEmpty(queue) ? "空" : "不为空";printf("队列长度为:%d\n队列是否为空:%s",queueLen(queue),s);queueDestory(&queue);return 0;}

运行截图:

好想从现在开始抱着你,紧紧地抱着你,一直走到上帝面前。

看数据结构写代码(16)顺序队列的实现(循环队列)

相关文章:

你感兴趣的文章:

标签云: