“这是我参与8月更文挑战的第1天,活动详情查看:8月更文挑战”
关注我,以下内容持续更新
循环队列的引入
队列是一种“先进先出”的存储结构,队列分为动态队列和静态队列两种。动态队列用链表实现,动态队列易于实现。静态队列用数组实现,静态队列通常都必须是循环队列。
静态队列为甚么必须是循环队列?
因为每删除一个元素的时候,front 指针向后移动一位,每插入一个元素的时候,rear 指针向后移动一位,假如rear移动到最后一个位置,这时候数据域还没有满,再插入元素时队列却发生了溢出,这种现象称为"假溢出"。为了解决这个问题,我们引入了循环队列。循环队列的思维非常简单,就是给定我们队列的大小范围,在原有队列的基础上,只要队列的后方满了,就从这个队列的前面开始进行插入,以达到重复利用空间的效果,由于循环队列的设计思维更像一个环,因此叫循环队列,但是它是单线性的。
循环队列的结构
循环队列中存放了data,front,reat,maxsize 四个元素:其中,data表示一个数据域,其可以存放任意类型的元素;maxsize表示循环队列的最大容纳量,也是data的数组长度,其表示队列的全部可操作空间,如果设置5,则队列的有效数据最大是4;front和rear初始值都是零,front代表头指针,front指向的是队列的第一个元素,rear代表尾指针,rear指向队列的最后一个元素的下一个元素。
1)出队时:取出data[front],front = (front + 1) % maxsize;
2)入队时:rear = (rear + 1) % maxsize;
3)判断队列为空:front == rear (但不一定为零);
4)判断队列满:两种方式
① (rear + 1) % maxsize == front
② 多增加一个标识参数flag,删除时为0,增加时为1,如果front == rear,则队满
循环队列的完整代码
//CircleQueue.h 文件
@interface CircleQueue : NSObject
- (instancetype)initWithMaxSize:(int)maxSize;
//队满
-(BOOL)isFull;
//队空
-(BOOL)isEmpty;
//入队
-(int)enqueue:(NSObject*)e;
//出队
-(NSObject*)dequeue;
//查看头元素
-(NSObject*)getFront;
// 求出当前队列有效数据的个数
-(int)getTotalCount;
//显示多有元素
-(void)showQueue;
@end
// CircleQueue.m 文件
#import "CircleQueue.h"
@interface CircleQueue()
/**用数组模拟队列*/
@property (nonatomic,strong) NSMutableArray * data;
/**最大值*/
@property (nonatomic,assign) int maxSize;
/**队头,指向队列第一个位置.*/
@property (nonatomic,assign) int front;
/**队尾, 指向队列的最后一个数据的后一个位置*/
@property (nonatomic,assign) int rear;
@end
@implementation CircleQueue
- (instancetype)initWithMaxSize:(int)maxSize
{
self = [super init];
if (self) {
self.maxSize = maxSize;
self.front = 0;
self.rear = 0;
//初始化数组
self.data = [[NSMutableArray alloc]initWithCapacity:maxSize];
for (int i = 0; i<maxSize; i++) {
[self.data addObject:[NSObject new]];
}
}
return self;
}
-(BOOL)isFull{
return (self.rear+1)%self.maxSize == self.front;
}
-(BOOL)isEmpty{
return self.front == self.rear;
}
-(int)enqueue:(NSObject*)e{
if ([self isFull]) {
NSLog(@"队列已满,无法加入");
return -1;
}
self.data[self.rear] = e;
self.rear = (self.rear+1)%self.maxSize;
NSLog(@"插入成功");
return 0;
}
-(NSObject*)dequeue{
if ([self isEmpty]) {
NSLog(@"队列为空,无法删除");
return NULL;
}
NSObject*ob = [self.data objectAtIndex:self.front];
self.front = (self.front+1)%self.maxSize;
return ob;
}
-(NSObject*)getFront{
return [self.data objectAtIndex:self.front];
}
-(int)getTotalCount{
return (self.rear-self.front + self.maxSize)%self.maxSize;
}
-(void)showQueue{
printf("打印所有元素\n");
if ([self isEmpty]) {
printf("队列为空 \n");
return;
}
int count = [self getTotalCount];
for (int i = self.front; i<self.front + count; i++) {
NSLog(@"第%d个元素:%@ \t",i%self.maxSize,self.data[i%self.maxSize]);
}
}
@end
//测试代码如下
-(void)circleQueueCase{
//设置 5, 其队列的有效数据最大是 4
CircleQueue*queue = [[CircleQueue alloc]initWithMaxSize:5];
//添加数据
[queue enqueue:@"a"];
[queue enqueue:@"b"];
[queue enqueue:@"c"];
[queue enqueue:@"d"];
[queue enqueue:@"z"];
printf("一共%d个元素 \n",[queue getTotalCount]);
//打印所有元素
[queue showQueue];
//查看头元素
NSObject*front = [queue getFront];
printf("头元素是:%s \n",front.description.UTF8String);
//删除数据
NSObject*str = [queue dequeue];
printf("删除的元素是:%s \n",str.description.UTF8String);
//打印所有元素
[queue showQueue];
//删除数据
[queue dequeue];
[queue dequeue];
printf("一共%d个元素 \n",[queue getTotalCount]);
[queue enqueue:@"e"];
[queue enqueue:@"f"];
[queue enqueue:@"g"];
[queue enqueue:@"h"];
//打印所有元素
[queue showQueue];
//删除数据
[queue dequeue];
[queue dequeue];
//打印所有元素
[queue showQueue];
}
关注我
如果觉得我写的不错,请点个赞 关注我 您的支持是我更文最大的动力!