欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

数组实现循环队列

程序员文章站 2024-03-18 11:21:52
...

循环队列作为一种常用的数据结构,它使头尾指针能够灵活的在容器头尾跳跃,实现循环存取的结构。线性队列,在不移动元素的情况下,随着数据的不断读写,会出现假上溢的情况(当尾部指针已经到了容器底部,线性队列就无法插入了,尽管存在已出队列的可以空间,),导致已出队列的可用空间无法再被利用。另外循环队列很适合作为缓存的处理。

//
//  CycleQueue.m
//  CycleQueue
//
//  Created by zengbailiang on 2018/5/8.
//  Copyright © 2018年 zengbailiang. All rights reserved.
//  循环队列

#import "CycleQueue.h"

#define CYCLE_QUEUE_MAX_SIZE 10
#define CYCLE_QUEUE_ELEMENT int

typedef struct kSCycleQueue
{
    CYCLE_QUEUE_ELEMENT data[CYCLE_QUEUE_MAX_SIZE];
    int fornt ,rear;
}*SCycleQueue;

@implementation CycleQueue

int queueInit(SCycleQueue *queue)
{
    if ((*queue) == NULL) {
        (*queue) = (SCycleQueue)malloc(sizeof(struct kSCycleQueue));
        //初始化队列头和队列尾部,队列尾初始化为-1是为了添加原始的时候统一操作为后移
        (*queue)->fornt = 0;
        (*queue)->rear = -1;
    }
    else
    {
        return -1;
    }
    return 1;
}

bool canAdd(SCycleQueue *queue)
{
    if((*queue) == NULL
       ||(*queue)->fornt + (*queue) ->rear + 1 == CYCLE_QUEUE_MAX_SIZE
       ||((*queue)->rear != -1 &&  (*queue)->rear + 1 == (*queue)->fornt))
    {
        return false;
    }
    else
    {
        return true;
    }
}

int add(SCycleQueue *queue,CYCLE_QUEUE_ELEMENT e)
{
    if (canAdd(queue)) {
        //如果已经是在最后一个原始,那么跳到第0个原始添加,实现循环
        if ((*queue) -> rear == CYCLE_QUEUE_MAX_SIZE - 1) {
            (*queue) -> rear = 0;
        }
        else
        {
            //非最后一个元素后移即可
            (*queue) -> rear += 1;
        }
        //队尾添加元素
        (*queue) ->data[(*queue) ->rear] = e;
        return 1;
    }
    else
    {
        return 0;
    }
    
}

int delete(SCycleQueue *queue,CYCLE_QUEUE_ELEMENT *e)
{
    if ((*queue) == NULL) {
        return  -1;
    }
    //如果rear不等于-1就代表存在元素
    else if((*queue)->fornt == 0 && (*queue)->rear == -1)
    {
        return 0;
    }
    else
    {
        (*e) = (*queue)->data[(*queue)->fornt];
        (*queue)->data[(*queue)->fornt] = -1;
        //如果 fornt == rear,代表最后一个元素了,这个时候把标记复位用于上面的判断。
        if ((*queue)->fornt == (*queue)->rear) {
            (*queue)->fornt = 0;
            (*queue)->rear = -1;
        }
        else if((*queue)->fornt == CYCLE_QUEUE_MAX_SIZE - 1)
        {
            //如果是最后一个元素出队列,那么队列头跳到容器第一个元素实现循环出队列
            (*queue)->fornt = 0;
        }
        else
        {
            (*queue)->fornt += 1;
        }
      return 1;
    }
}

+ (void)testt
{
    test();
    test1();
    test2();
}

void test()
{
    SCycleQueue queue;
    queueInit(&queue);
    add(&queue, 0);
    add(&queue, 1);
    add(&queue, 2);
    add(&queue, 3);
    add(&queue, 4);
    add(&queue, 5);
    add(&queue, 6);
    add(&queue, 7);
    add(&queue, 8);
    add(&queue, 9);//加满
    CYCLE_QUEUE_ELEMENT e;
    delete(&queue, &e);
    delete(&queue, &e);
    delete(&queue, &e);
    delete(&queue, &e);
    delete(&queue, &e);
    add(&queue, 10);//容器底部已满,循环到头部开始添加
    add(&queue, 11);
    add(&queue, 12);
    add(&queue, 13);
    add(&queue, 14);
}
void test1()
{
    SCycleQueue queue;
    queueInit(&queue);
    add(&queue, 0);
    add(&queue, 1);
    add(&queue, 2);
    add(&queue, 3);
    add(&queue, 4);
    add(&queue, 5);
    add(&queue, 6);
    add(&queue, 7);
    add(&queue, 8);
    add(&queue, 9);
    CYCLE_QUEUE_ELEMENT e;
    delete(&queue, &e);
    delete(&queue, &e);
    delete(&queue, &e);
    delete(&queue, &e);
    delete(&queue, &e);
    delete(&queue, &e);
    delete(&queue, &e);
    delete(&queue, &e);
    delete(&queue, &e);
    delete(&queue, &e);//全部出队列,标记复位
    delete(&queue, &e);
    add(&queue, 6);
    add(&queue, 7);
    add(&queue, 8);
    add(&queue, 9);
}

void test2()
{
    SCycleQueue queue;
    queueInit(&queue);
    add(&queue, 0);
    add(&queue, 1);
    add(&queue, 2);
    add(&queue, 3);
    add(&queue, 4);
    add(&queue, 5);
    add(&queue, 6);
    add(&queue, 7);
    add(&queue, 8);
    add(&queue, 9);
    CYCLE_QUEUE_ELEMENT e;
    delete(&queue, &e);
    delete(&queue, &e);
    delete(&queue, &e);
    delete(&queue, &e);
    delete(&queue, &e);//font = 5
    add(&queue, 15);
    add(&queue, 16);
    add(&queue, 11);
    add(&queue, 12);
    add(&queue, 13);
    delete(&queue, &e);
    delete(&queue, &e);
    delete(&queue, &e);
    delete(&queue, &e);
    delete(&queue, &e);//循环到容器头出队列
    delete(&queue, &e);
    delete(&queue, &e);
    delete(&queue, &e);
    delete(&queue, &e);
    delete(&queue, &e);
}

@end

上一篇: 现场实验 AJAX 的异步功能

下一篇: