数据机构(10)--顺序循环队列的实现及相关操作
2016-02-21 14:56
501 查看
参考书籍:数据结构(C语言版)严蔚敏吴伟民编著清华大学出版社
#define maxsize 100/*队列的最大容量*/
typedef char QElemtype;
struct Queue
{ QElemtype data[maxsize ]; //队员的存储空间
int front; //队头队尾指针
int rear; //队尾指针
};
定义一个顺序队的变量: Queue Q;
队列的数据区为:Q.data[0]---Q.data[maxsize -1]
队头指针:Q.front 队尾指针:Q.rear
约定队头指针指向队头元素,队尾指针指向队尾元素后面一个位置(这样的设置是为了某些运算的方便,并不是唯一的方法)。
从下图中可以看到,随着入队出队的进行,会使整个队列整体向后移动,这样就出现了图(d)中的现象:队尾指针已经移到了最后,再有元素入队就会出现溢出,而事实上此时队中并未真的“满员”,这种现象为“假溢出”,这是由于“队尾入队头出”这种受限制的操作所造成。
解决上面的问题一个巧妙的方法就是:将顺序队列臆造成一个环状的空间,如下图,称之为循环队列。
#define MAXSIZE 30
typedef char QElemType;
typedef struct{
QElemType data[MAXSIZE];
int f;//头指针
int r;//尾指针
}SqQueue;
因为是头尾相接的循环结构,入队时的队尾指针加1操作修改为:Q.rear=(Q.rear+1) % (n0+1);
出队时的队头指针加1操作修改为:Q.front=(Q.front+1) % (n0+1);
设n0=9,图是循环队列操作示意图。
从图的循环队可以看出,在队空情况下有:front==rear,在队满情况下也有:front==rear就是说“队满”和“队空”的条件是相同的了。这显然是必须要解决的一个问题。
方法之一是附设一个存储队中元素个数的变量如num,当num==0时队空,当num==maxsize时为队满。
另一种方法是少用一个元素空间,把图(d)所示的情况就视为队满,此时的状态是队尾指针加1就会从后面赶上队头指针,这种情况下队满的条件是:(rear+1) % maxsize ==front,也能和空队区别开。
下面的循环队列及操作按第二种方法实现。
队空:front==rear
队满: (rear+1) mod maxsize ==front
队中元素个数n=(rear-front+maxsize )mod maxsize
入队:rear=(rear+1) % maxsize ;
出队:front=(front+1) % maxsize ;
1.顺序队列
顺序队列的类型定义如下:#define maxsize 100/*队列的最大容量*/
typedef char QElemtype;
struct Queue
{ QElemtype data[maxsize ]; //队员的存储空间
int front; //队头队尾指针
int rear; //队尾指针
};
定义一个顺序队的变量: Queue Q;
队列的数据区为:Q.data[0]---Q.data[maxsize -1]
队头指针:Q.front 队尾指针:Q.rear
约定队头指针指向队头元素,队尾指针指向队尾元素后面一个位置(这样的设置是为了某些运算的方便,并不是唯一的方法)。
从下图中可以看到,随着入队出队的进行,会使整个队列整体向后移动,这样就出现了图(d)中的现象:队尾指针已经移到了最后,再有元素入队就会出现溢出,而事实上此时队中并未真的“满员”,这种现象为“假溢出”,这是由于“队尾入队头出”这种受限制的操作所造成。
解决上面的问题一个巧妙的方法就是:将顺序队列臆造成一个环状的空间,如下图,称之为循环队列。
2.顺序循环队列
顺序循环队列的定义#define MAXSIZE 30
typedef char QElemType;
typedef struct{
QElemType data[MAXSIZE];
int f;//头指针
int r;//尾指针
}SqQueue;
因为是头尾相接的循环结构,入队时的队尾指针加1操作修改为:Q.rear=(Q.rear+1) % (n0+1);
出队时的队头指针加1操作修改为:Q.front=(Q.front+1) % (n0+1);
设n0=9,图是循环队列操作示意图。
从图的循环队可以看出,在队空情况下有:front==rear,在队满情况下也有:front==rear就是说“队满”和“队空”的条件是相同的了。这显然是必须要解决的一个问题。
方法之一是附设一个存储队中元素个数的变量如num,当num==0时队空,当num==maxsize时为队满。
另一种方法是少用一个元素空间,把图(d)所示的情况就视为队满,此时的状态是队尾指针加1就会从后面赶上队头指针,这种情况下队满的条件是:(rear+1) % maxsize ==front,也能和空队区别开。
下面的循环队列及操作按第二种方法实现。
队空:front==rear
队满: (rear+1) mod maxsize ==front
队中元素个数n=(rear-front+maxsize )mod maxsize
入队:rear=(rear+1) % maxsize ;
出队:front=(front+1) % maxsize ;
3.顺序循环队列相关操作的实现
3.1顺序循环队列的定义
/*顺序循环队列:少用一个元素空间,约定以“队列头指针在队列尾指针的下一位置(环状的下一位置)上”作为队列“满”状态的标志 即,队满:Q.f == (R.r + 1)%MAXSIZE 对空:Q.f == Q.r 队长:(Q.r - Q.f + MAXSIZE)%MAXSIZE 入队时尾指针后移:Q.r = (Q.r + 1)%MAXSIZE 出队时头指针后移:Q.f = (Q.f + 1)%MAXSIZE */ #include<stdio.h> #define MAXSIZE 30 typedef char QElemType; typedef struct{ QElemType data[MAXSIZE]; int f;//头指针 int r;//尾指针 }SqQueue;
3.2初始化一个空队列
//初始化一个空队列 void initQueue(SqQueue &Q){ Q.f = Q.r = 0; }
3.3求队列长度
//求队列长度 int getQueueLength(SqQueue Q){ return (Q.r - Q.f + MAXSIZE)%MAXSIZE; }
3.4入队操作
//入队操作,尾指针后移 void enQueue(SqQueue &Q, QElemType e){ //先判断队列是否已满 if(Q.f == (Q.r + 1)%MAXSIZE){ printf("队列已满,入队操作失败!\n"); return; } Q.data[Q.r] = e; Q.r = (Q.r + 1)%MAXSIZE; }
3.5出队操作
//出队操作,头指针后移,e返回出队元素值 void deQueue(SqQueue &Q, QElemType &e){ //先判断队列是否为空 if(Q.f == Q.r){ printf("队列已空,出队操作失败!\n"); return; } e = Q.data[Q.f]; printf("元素%c出队\n", e); Q.f = (Q.f + 1)%MAXSIZE; }
3.6利用入队操作创建队列
//利用入队操作创建一个队列,他含有n个元素 void createQueue(SqQueue &Q, int n){ int i = 0; printf("请输入%d个字符队列元素:\n", n); while(i < n){ QElemType e; scanf("%c", &e); enQueue(Q, e); i++; getchar();//吃掉回车符 } }
3.7打印队列
void printQueue(SqQueue Q){ printf("打印队列:"); int i = Q.f; while(i%MAXSIZE != Q.r){ printf("%c ", Q.data[i]); i++; } printf("\n\n"); }
4.演示
void main(){ SqQueue Q; initQueue(Q); createQueue(Q, 5); printQueue(Q); printf("执行入队操作:"); printf("请输入您要入队的字符元素:"); QElemType e; scanf("%c", &e); enQueue(Q, e); printQueue(Q); printf("执行出队操作:"); deQueue(Q, e); printQueue(Q); }
相关文章推荐
- LA 3641 置换
- android - Support 包
- 移动开发兼容性问题及性能优化
- 小幻美图 API
- [LeetCode]86. Partition List
- 杂七杂八的记录
- 大数据时代,信息革命
- 代码大全(2) - 三思而后行:前期准备
- JAVA多线程-Lock的使用(三)-Lock与Condiition相关的方法
- Leetcode 169. Majority Element
- Android 地理位置Location服务之LocationManager,Geocoder详解
- 【Linux 开发篇】之 vim插件
- 介绍一篇不错的CUDA入门博客
- On Peace
- Struts2 用action属性接收参数
- 2016大连理工大学计算机科学与技术考研经验
- 基于Linux 3.0.8 Samsung FIMC(S5PV210) 的摄像头驱动框架解读(一)
- MONGODB(四)——DBObject与JavaBean转换
- 抽象类总结
- 334. Increasing Triplet Subsequence