数据结构与算法三:1)队列之循环队列 | 8月更文挑战

332 阅读4分钟

这是我参与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];
}

下一篇 数据结构与算法三:2)队列之动态队列(单链表实现)

关注我

如果觉得我写的不错,请点个赞 关注我 您的支持是我更文最大的动力!